POJ 2184 Cow Exhibition(变形01背包)
2016-04-13 14:45
399 查看
题目链接:
POJ 2184 Cow Exhibition
题意:
给n头牛,每头牛有两个属性:smart和fun,选出若干头牛使得这些牛的smart和fun之和最大,并且smart和与fun和均不为负。
每头牛的smart和fun可以为负。
分析:
01背包和滚动数组。
用dp[j]表示得到smart和为j时的fun和最大值。但是因为j可能为负,一开始我是用map,但是一直TLE。。。
后来改成二维表示:
初始化:
dp为最小,但是dp[0][0]=dp[0][1]=0;
状态转移方程需要注意要根据smart[i]的正负确定遍历的顺序,而且还要考虑j-smart[i]的正负。
最后再遍历扫一下dp[j][0]取最大就好了。
POJ 2184 Cow Exhibition
题意:
给n头牛,每头牛有两个属性:smart和fun,选出若干头牛使得这些牛的smart和fun之和最大,并且smart和与fun和均不为负。
每头牛的smart和fun可以为负。
分析:
01背包和滚动数组。
用dp[j]表示得到smart和为j时的fun和最大值。但是因为j可能为负,一开始我是用map,但是一直TLE。。。
后来改成二维表示:
dp[j][0]:smart和为j(j>0)时的最大fun和,dp[j][1]:smart和为-j(j<0)时的最大fun和
初始化:
dp为最小,但是dp[0][0]=dp[0][1]=0;
状态转移方程需要注意要根据smart[i]的正负确定遍历的顺序,而且还要考虑j-smart[i]的正负。
最后再遍历扫一下dp[j][0]取最大就好了。
//600K 47MS #include <cstdio> #include <cstring> #include <algorithm> #include <climits> using namespace std; const int MAX_N=110; const int MAX_M=110000; const int inf=INT_MIN/3; int n; int smart[MAX_N],fun[MAX_N],dp[MAX_M][2]; int main() { //freopen("Lin.txt","r",stdin); //freopen("Lout.txt","w",stdout); while(~scanf("%d",&n)){ int max_sum=0,min_sum=0; for(int i=1;i<=n;i++){ scanf("%d%d",&smart[i],&fun[i]); if(smart[i]>0) max_sum+=smart[i]; else min_sum+=smart[i]; } for(int j=1;j<=max(abs(min_sum),abs(max_sum))+1100;j++){ dp[j][0]=dp[j][1]=inf; } dp[0][0]=dp[0][1]=0; for(int i=1;i<=n;i++){ if(smart[i]>=0){ for(int j=max_sum;j>=0;j--){ if(j-smart[i]<=0&&dp[-(j-smart[i])][1]!=inf) dp[j][0]=max(dp[-(j-smart[i])][1]+fun[i],dp[j][0]); else if(j-smart[i]>=0&&dp[j-smart[i]][0]!=inf) dp[j][0]=max(dp[j-smart[i]][0]+fun[i],dp[j][0]); //printf("i=%d j=%d dp[abs(j)][0]=%d\n",i,j,dp[abs(j)][0]); } for(int j=0;j>=min_sum;j--){ if(j-smart[i]<=0&&dp[-(j-smart[i])][1]!=inf) dp[-j][1]=max(dp[-(j-smart[i])][1]+fun[i],dp[-j][1]); else if(j-smart[i]>=0&&dp[j-smart[i]][0]!=inf) dp[-j][1]=max(dp[j-smart[i]][0]+fun[i],dp[-j][1]); //printf("i=%d j=%d dp[abs(j)][1]=%d\n",i,j,dp[abs(j)][1]); } }else { for(int j=min_sum;j<=0;j++){ if(j-smart[i]<=0&&dp[-(j-smart[i])][1]!=inf) dp[-j][1]=max(dp[-(j-smart[i])][1]+fun[i],dp[-j][1]); else if(j-smart[i]>=0&&dp[j-smart[i]][0]!=inf) dp[-j][1]=max(dp[j-smart[i]][0]+fun[i],dp[-j][1]); //printf("i=%d j=%d dp[abs(j)][1]=%d\n",i,j,dp[abs(j)][1]); } for(int j=0;j<=max_sum;j++){ if(j-smart[i]<=0&&dp[-(j-smart[i])][1]!=inf) dp[j][0]=max(dp[-(j-smart[i])][1]+fun[i],dp[j][0]); else if(j-smart[i]>=0&&dp[j-smart[i]][0]!=inf) dp[j][0]=max(dp[j-smart[i]][0]+fun[i],dp[j][0]); //printf("i=%d j=%d dp[abs(j)][0]=%d\n",i,j,dp[abs(j)][0]); } } } int ans=0; for(int i=max_sum;i>=0;i--){ if(dp[i][0]>=0){ ans=max(ans,i+dp[i][0]); //printf("i=%d dp[i][0]=%d\n",i,dp[i][0]); } } printf("%d\n",ans); } return 0; }
相关文章推荐
- 初学ACM - 组合数学基础题目PKU 1833
- POJ ACM 1001
- POJ ACM 1002
- 1611:The Suspects
- POJ1089 区间合并
- POJ 2635 The Embarrassed Cryptographe
- POJ 3292 Semi-prime H-numbers
- POJ 2773 HAPPY 2006
- POJ 3090 Visible Lattice Points
- POJ-2409-Let it Bead&&NYOJ-280-LK的项链
- POJ-1695-Magazine Delivery-dp
- POJ1523 SPF dfs
- POJ-1001 求高精度幂-大数乘法系列
- POJ-1003 Hangover
- POJ-1004 Financial Management
- 用单调栈解决最大连续矩形面积问题
- 2632 Crashing Robots的解决方法
- 1573 Robot Motion (简单题)
- POJ 1200 Crazy Search(简单哈希)
- 【高手回避】poj3268,一道很水的dijkstra算法题