Cow Exhibition POJ 2184(01背包dp)

原题

题目链接

题目分析

明显的01背包,但还是由细节需要处理,设置dp[i][j]=前i头牛中选的TF为j时最大的TS值,由于TF可能为负数因此要加一个基数使其在大于等于零,dp初始化为-1,dp[0][0]=0.更新的时候dp[i][j]=max(dp[i-1][j-f[i]]+s[i],dp[i-1][j]).观察这个dp的更新可以发现能状态压缩,当f[i]>=0时,j从大到小更新,当f[i]<0时,j从小到大更新.最后从基数往上扫dp[j]+j-基数的最大值就是答案,注意前提是dp[i]>=0.

代码

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <utility>
 4 #include <cstdio>
 5 #include <cmath>
 6 #include <cstring>
 7 #include <string>
 8 #include <vector>
 9 #include <stack>
10 #include <queue>
11 #include <map>
12 #include <set>
13
14 using namespace std;
15 typedef long long LL;
16 const int INF_INT=0x3f3f3f3f;
17 const LL INF_LL=0x3f3f3f3f3f3f3f3f;
18
19 struct N
20 {
21     int s,f;
22 }cow[200];
23 int dp[300000];
24
25 bool cmp(N a,N b)
26 {
27     return a.s>b.s;
28 }
29
30 int main()
31 {
32 //    freopen("black.in","r",stdin);
33 //    freopen("black.out","w",stdout);
34     int n;
35     cin>>n;
36     int uplimit=0,downlimit=0;
37     for(int i=1;i<=n;i++)
38     {
39         cin>>cow[i].s>>cow[i].f;
40         if(cow[i].f>0) uplimit+=cow[i].f;
41         else downlimit+=cow[i].f;
42     }
43     sort(cow+1,cow+n+1,cmp);
44     int limit=max(uplimit,abs(downlimit));
45 /*    printf("limit=%d\n",limit);
46     for(int i=1;i<=n;i++) printf("cow %d s %d f %d\n",i,cow[i].s,cow[i].f);*/
47     for(int j=0;j<=2*limit;j++) dp[j]=-1*INF_INT;
48     dp[limit]=0;
49     for(int i=1;i<=n;i++)
50     {
51         if(cow[i].f>=0)
52         {
53             for(int j=2*limit;j>=0;j--)
54             {
55                 int from=j-cow[i].f;
56                 if(from>=0&&from<=limit*2&&dp[from]!=-1*INF_INT)
57                 {
58                     dp[j]=max(dp[j],dp[from]+cow[i].s);
59                 }
60             }
61         }
62         else
63         {
64             for(int j=0;j<=2*limit;j++)
65             {
66                 int from=j-cow[i].f;
67                 if(from>=0&&from<=limit*2&&dp[from]!=-1*INF_INT)
68                 {
69                     dp[j]=max(dp[j],dp[from]+cow[i].s);
70                 }
71             }
72         }
73   //      for(int j=0;j<=2*limit;j++) if(dp[now][j]!=-1) printf("dp %d %d=%d\n",i,j-limit,dp[now][j]);
74     }
75     int ans=0;
76     for(int i=limit;i<=limit*2;i++) if(dp[i]>=0) ans=max(ans,dp[i]+i-limit);
77     cout<<ans<<endl;
78     return 0;
79 }

原文地址:https://www.cnblogs.com/VBEL/p/11415356.html

时间: 2024-11-05 17:30:10

Cow Exhibition POJ 2184(01背包dp)的相关文章

poj 2184 0---1背包的变形

这题是0--1背包的变形,对理解0--1背包有很大的帮组 题意:要选一些牛去参见展览,每个牛有幽默.智慧两个选择标准,要求选的这些牛使得幽默和智慧的总和最大且幽默和智慧的每个总和都必须是大于等于0: 刚看的这个题目是时候,知道是一个0--1背包的的题目,但就是不知道怎么来写出状态转移方程,因为题中的两个变量都是有负值的. 看了大牛的解题报告才知道. 我们可以把幽默个变量看成是体积 , 智慧看成是价值. 我们可以把每个牛幽默的值 , 放在一个坐标上,让后整体往右移,使得最小值为 0 , 那么这时候

poj 2184 Cow Exhibition 【另类01背包】

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 9424   Accepted: 3619 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 t

poj 2484 Cow Exhibition 【变形0-1背包】

题目:poj 2484 Cow Exhibition 题意:给出n头牛,每头牛有一个幸运值 si 和聪明值 ti ,现在要选出一些牛,让两个值的和最大,前提是sum(si)和sum(ti)都是非负值. 分析:此题数据量不大,可以暴搜+剪枝水过. 这里要说的是0-1背包的思想,这个题目明显的变形就是物品有两个属性值,而且都要选最大的. 那么我们可不可以把一个值固定下来来求另一个值的最大值,根据0-1背包的思想,定义状态:dp[i]表示装入一些物品使得sum(si)的时候最大的sum(ti)的值.

POJ 2184 01背包+负数处理

Cow Exhibition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 10200   Accepted: 3977 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

挑战程序设计竞赛2.3习题:Cow Exhibition POJ - 2184

"Fat and docile, big and dumb, they look so stupid, they aren't muchfun..."- 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

Cow Exhibition POJ - 2184

"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

POJ 1384 Piggy-Bank 背包DP

所谓的完全背包,就是说物品没有限制数量的. 怎么起个这么intimidating(吓人)的名字? 其实和一般01背包没多少区别,不过数量可以无穷大,那么就可以利用一个物品累加到总容量结尾就可以了. 本题要求装满的,故此增加个限制就可以了. #include <stdio.h> #include <stdlib.h> #include <string.h> inline int min(int a, int b) { return a < b? a : b; } c

poj 1837 01背包

Balance Time Limit: 1000 MS Memory Limit: 30000 KB 64-bit integer IO format: %I64d , %I64u Java class name: Main [Submit] [Status] [Discuss] Description Gigel has a strange "balance" and he wants to poise it. Actually, the device is different fr

POJ 3624 01背包

初学DP,用贪心的思想想解题,可是想了一个多小时还是想不出. //在max中的两个参数f[k], 和f[k-weight[i]]+value[i]都是表示在背包容量为k时的最大价值 //f[k]是这个意思,就不用说了. //而f[k-weight[i]]+value[i]也表示背包容量为k时的最大价值是为什么呢? //首先,f[k-weight[i]]表示的是背包容量为k-weight[i]的容量,也就是说f[k-weight[i]] //表示的是容量还差weiht[i]才到k的价值,+walu