1365: Pku2184 Cow exhibition
Description
Bessie要从她的N头奶牛中选出一些奶牛去参加展览,她已经给出了每头奶牛的两个指标,Si和Fi(-1000<=Si,Fi<=1000),分别代表每头奶牛的聪明指数和快乐指数。当然她希望所挑选奶牛的Si和Fi的总和最大,而且为了显示她的奶牛是全面发展的,Si和Fi各自的和数不能小于0。
Input
第1行:奶牛总数N ,N<=100
第2到N+1行:每头奶牛的Si和Fi
Si (-1000 <= Si <= 1000)
Fi (-1000 <= Fi <= 1000)
第2到N+1行:每头奶牛的Si和Fi
Si (-1000 <= Si <= 1000)
Fi (-1000 <= Fi <= 1000)
Output
符合条件的Si和Fi的最大总和
Sample Input
5
-5 7
8 -6
6 -3
2 1
-8 -5
Sample Output
8
这道题是一道比较经典的01背包的变形题
Dominos这道题也是一道类似的题目,
还可以用搜索来做。把有利的值统统加入,同时记下可能使不符合的元素,做一次排除,找到正确的最优值。
0-1背包有时(分堆)可以用随机贪心来做的,大致思路是从多的一堆中随机一个放入少的一堆中。
所以这道题最坑的地方
初始化要将 数组 f 赋值为 -0x3fffffff(其实-200000就够了) 并把f[1000000] = 0 因为幽默度能可能出现
负数。
见代码
#include<bits/stdc++.h> using namespace std; const int INF=0x3f3f3f3f; int dp[200001]; int value[101]; int weight[101]; int n; int main() { int k=100000; while(~scanf("%d",&n)) { for(int i=0;i<n;i++) { scanf("%d%d",&value[i],&weight[i]); } for(int i=0;i<=200000;i++)dp[i]=-INF; dp[k]=0; for(int i=0;i<n;i++) { if(value[i]>0) { for(int j=200000;j>=value[i];j--) if(dp[j-value[i]]>-INF) dp[j]=max(dp[j],dp[j-value[i]]+weight[i]); } else { for(int j=0;j<=200000+value[i];j++) if(dp[j-value[i]]>-INF) dp[j]=max(dp[j],dp[j-value[i]]+weight[i]); } } int ans=0; for(int i=100000;i<=200000;i++) if(dp[i]>=0&&dp[i]+i-100000>ans) ans=dp[i]+i-100000; printf("%d\n",ans); } return 0; }