POJ 2184 Cow Exhibition [动态规划 01背包]

来源:互联网 发布:傻丫头是什么软件 编辑:程序博客网 时间:2024/06/06 09:33

题干

Description

“Fat and docile, big and dumb, they look so stupid, they aren’t much
fun…”
- Cows with Guns by Dana Lyons

The cows want to prove to the public that they are both smart and fun. In order to do this, Bessie has organized an exhibition that will be put on by the cows. She has given each of the N (1 <= N <= 100) cows a thorough interview and determined two values for each cow: the smartness Si (-1000 <= Si <= 1000) of the cow and the funness Fi (-1000 <= Fi <= 1000) of the cow.

Bessie must choose which cows she wants to bring to her exhibition. She believes that the total smartness TS of the group is the sum of the Si’s and, likewise, the total funness TF of the group is the sum of the Fi’s. Bessie wants to maximize the sum of TS and TF, but she also wants both of these values to be non-negative (since she must also show that the cows are well-rounded; a negative TS or TF would ruin this). Help Bessie maximize the sum of TS and TF without letting either of these values become negative.
Input

  • Line 1: A single integer N, the number of cows

  • Lines 2..N+1: Two space-separated integers Si and Fi, respectively the smartness and funness for each cow.

Output

  • Line 1: One integer: the optimal sum of TS and TF such that both TS and TF are non-negative. If no subset of the cows has non-negative TS and non- negative TF, print 0.

Sample Input

5
-5 7
8 -6
6 -3
2 1
-8 -5
Sample Output

8

题解

/***动态规划01背包问题,价值和体积可以互换角色,最终答案只要处理一下,结果就一样*枚举价值或者体积,去找另一个的最优值*那如何去找哪两个属性是体积和价值呢?可以很明显发现的是,体积和价值相互制约*想价值更优,结果体积不允许; 想体积更优,结果又限制于价值*01背包问题就是拿或者不拿的问题*这个问题里面,先枚举smart值,再保证fun是最优的,最后再把求两者加起来后*哪一个最大,之所以这样可以,是因为,假设我们找到一个最优的smart + fun*那么这个smart值我们一定可以枚举到,如果fun比我们找到的最优fun小,那么这个*就不是最优,如果fun比我们找到的最优fun大,那么我们找到的就不是最优fun,*所以fun一定等于我们找到的最优fun,所以最终结果正确*/#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int inf = 0x3f3f3f3f;const int MAXS = 200000;//枚举TS可能的取值时,从0开始,枚举到MAXS结束,//而不是从-100000到+100000,因为数组下标不能取负数,要偏移const int shift = 100000;int dp[MAXS + 1];int main(){    //freopen("in.txt","r",stdin);    int N,s[110],f[110];    while(~scanf("%d",&N)){        for(int i=1;i<=N;i++){            scanf("%d%d",&s[i],&f[i]);        }        memset(dp,-inf,sizeof(dp));//恰好装满的背包,初始时只有原点处有意义,        //其他位置暂时没有意义        dp[shift] = 0;//定义原点        for(int i=1; i<=N; i++){            if(s[i]>0){                //恰好装满的背包问题,当s[i]>0, 应从右向左遍历                for(int j=MAXS;j>=s[i];j--){                    dp[j] = max(dp[j], dp[j - s[i]] + f[i]);                }            }else {                //恰好装满的背包问题,当s[i]<0, 应从左向右遍历                for(int j=0;j-s[i]<=MAXS;j++){                    dp[j] = max(dp[j], dp[j - s[i]] + f[i]);                }            }        }        int ans = 0;        //从shift开始遍历,保证TS为正        for(int i=shift; i<=MAXS; i++){            //ans 为dp[i] + i - shift            //if语句,保证TF为正            if(dp[i] >= 0)ans = max(ans, dp[i] + i - shift);        }        printf("%d\n",ans);    }    return 0;}
0 0
原创粉丝点击