本题抄自staginner(斌哥)。。
先做一下心得体会:我被这题虐了。。。。话说这题当时还是上个月看的。当然,抄完这题也真的很长见识的。有的时候,真的不是说想不出来,而是根本不敢去想,或者说没深入的去想这个问题,就直接把自己的假设枪毙了。
先复述一下斌哥的思路:
1.首先,我们需要知道,当力量较大的乌龟置于下面时,对这两只乌龟来说,他们的总体承重能力是肯定大于当力量较小的乌龟置于下面的时候的。
这个可以简单的证明一下:
假设力量大的乌龟的力量是s1,自重是w1;力量小的乌龟的力量是s2,自重是w2;(s1>s2)
当力量较大的乌龟在下面时,假设他们的总体承重能力是A,那么A=min{s1-w1-w2,s2-w2}
当力量较小的乌龟在下面时,假设他们的总体承重能力是B,那么B=min{s2-w1-w2,s1-w1}=s2-w1-w2【因为(s2-w1-w2)-(s1-w1)=s2-s1-w2<0】
显然B<A。原命题得证。
2.有了以上的结论,我们就必然需要将乌龟的顺序按力量的大小排列了。
3.令DP数组dp[i]表示当乌龟达到i个时,全部乌龟最轻的重量。这个用滚动数组就可以实现,通过逆序枚举来不断更新dp[i],以及当前乌龟累计数达到的最大值max。
下面贴代码:
View Code
1 #include <iostream> 2 #include <algorithm> 3 using namespace std; 4 class turtle 5 { 6 public: 7 int weigh; 8 int strength; 9 }; 10 int cmp(turtle A,turtle B)//力量升序 11 { 12 return A.strength < B.strength; 13 } 14 turtle t[5610]; 15 int dp[5610]; 16 #define INF 1<<30 17 int main() 18 { 19 int max = 0,i = 1,j,num = 0; 20 while(cin>>t[i].weigh>>t[i].strength) 21 { 22 /*if(t[i].weigh == 0 && t[i].strength == 0) 23 break;*/ 24 i++; 25 num++; 26 } 27 sort(t + 1,t + num + 1,cmp); 28 dp[0] = 0; 29 for(i = 1;i <= num;i++) 30 dp[i] = INF; 31 for(i = 1;i <= num;i++) 32 { 33 for(j = max;j >= 0;j--) 34 { 35 if(dp[j] + t[i].weigh <= t[i].strength && dp[j] + t[i].weigh < dp[j + 1]) 36 //当前这只龟的体重加上前j只龟的体重不超过这只龟的承重能力 且 算上这只龟与前j只龟的总重小于原j+1只龟的总重 37 { 38 dp[j + 1] = dp[j] + t[i].weigh; 39 if(j + 1 > max) 40 max = j + 1; 41 } 42 } 43 } 44 cout<<max<<endl; 45 //system("pause"); 46 return 0; 47 }