题目(HDU - 1677)
Nested Dolls
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 4020 Accepted Submission(s): 1248
分析
如果你还不了解Dilworth定理,那你可以翻阅一下之前的一篇博客。
然后再来看一看这道题目。题目很友好的一上来就告诉我们有一个叫Dilworth的人收集套娃。如果你知道这个定理,那这个提醒就不能再明显了啊。题目要求最后的最少分成几组套娃。这显然是求链的个数。那么根据Dilworth定理,我们要求的是其最长反链的长度。如果你眼尖,可能看出这道题跟木棍加工很像。但又有一些区别,比如,木棍允许宽度和长度中只要有一个满足即可,但是套娃必须宽度小于前一个套娃,高度也小于前一个套娃才能套进去。
排序函数也要做一些调整。这里是先按照一个做升序排列,如果这个关键字相同,那么按另一个关键字降序排列。其实这是一个贪心的思想,为了能套进更多的套娃,在其中一个关键字相同时,另一个关键字越大,就更有可能套进多的套娃。另外的微调即可,包括LIS中要存储两个关键字等。
程序
1 #include<bits/stdc++.h> 2 using namespace std; 3 const int Max_Stick=20000+10; 4 5 struct Node{int Length,Weight;}Stick[Max_Stick]; 6 Node LIS[Max_Stick]; 7 int N_Stick,Len_LIS=0; 8 bool Compare(Node X,Node Y) 9 { 10 if(X.Length!=Y.Length) 11 return X.Length<Y.Length; 12 return X.Weight>Y.Weight; 13 } 14 15 int main() 16 { 17 int i,j; 18 int t; 19 cin >> t; 20 while(t--) 21 { 22 memset(Stick,0,sizeof(Stick)); 23 memset(LIS,0,sizeof(LIS)); 24 Len_LIS=0; 25 scanf("%d",&N_Stick); 26 for (i=0;i<N_Stick;i++) 27 scanf("%d%d",&Stick[i].Length,&Stick[i].Weight); 28 sort(Stick,Stick+N_Stick,Compare); 29 for(i=0;i<N_Stick;i++) 30 { 31 int Flag=false; 32 for (j=0;j<Len_LIS;j++) 33 if (LIS[j].Length<Stick[i].Length&&LIS[j].Weight<Stick[i].Weight) 34 { 35 LIS[j].Length=Stick[i].Length; 36 LIS[j].Weight=Stick[i].Weight; 37 Flag=true; 38 break; 39 } 40 if (!Flag) 41 { 42 LIS[Len_LIS].Length=Stick[i].Length; 43 LIS[Len_LIS].Weight=Stick[i].Weight; 44 Len_LIS++; 45 } 46 } 47 printf("%d\n",Len_LIS); 48 } 49 return 0; 50 }