0-1背包问题变形------------cow exhibition

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)

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;
}

 

 

 
posted @ 2019-05-31 15:18  小向同学  阅读(429)  评论(0编辑  收藏  举报