1365: Pku2184 Cow exhibition
DescriptionBessie要从她的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;
}
来源:https://www.cnblogs.com/kevin6666/p/10952138.html