标签:
http://poj.org/problem?id=2184
n只奶牛,每只都有智商s_i和情商f_i,取出若干只,保证智商之和与情商之和都不为负的情况下,让两者之和最大.
是一个关于取与不取得问题,而当智商之和一定时,情商之和越大越好,所以类似01背包,用智商之和作为dp数组下标,dp[i]表示智商之和为i时,情商的最大值,动规结束后扫一遍,找到符合要求的最有答案即可.
但是注意这里用智商之和作为下标时,智商之和有可能为负,所以用idx把整个数组向右移.统计智商之和最小的值,向右移动这个值即可.则dp[i]表示的是智商之和为(i-idx)的情商最大值.
注意:
1.开始时dp数组要全部赋为赋值.
2.赋的值不能使-0x7fffffff,因为可能会和负的情商相加...(貌似不是第一次犯这种错误了0.0)
#include <cstdio> #include <algorithm> #define for1(i,a,n) for(int i=(a);i<=(n);i++) #define read(a) a=getnum() using namespace std; const int INF=1<<27; int n,mins,maxs; int s[100+5],f[100+5]; int dp[1000*100*2+5]; inline int getnum(){int r=0,k=1;char c;for(c=getchar();c<‘0‘||c>‘9‘;c=getchar())if(c==‘-‘)k=-1;for(;c>=‘0‘&&c<=‘9‘;c=getchar())r=r*10+c-‘0‘;return r*k;} void solve() { int idx=mins; int range=idx+maxs; for1(i,0,range) dp[i]=-INF; dp[idx]=0; for1(i,1,n) { if(s[i]>=0) { for(int j=range;j>=s[i];j--) { dp[j]=max(dp[j],dp[j-s[i]]+f[i]); } } else { for(int j=0;j-s[i]<=range;j++) { dp[j]=max(dp[j],dp[j-s[i]]+f[i]); } } } int ans=-INF; for(int i=idx;i<=range;i++) { if(dp[i]<0) continue; ans=max(ans,i-idx+dp[i]); } printf("%d\n",ans); } void init() { read(n); for1(i,1,n) { read(s[i]); read(f[i]); if(s[i]>0) maxs+=s[i]; else mins-=s[i]; } } int main() { #ifndef ONLINE_JUDGE freopen("cow.in","r",stdin); freopen("cow.out","w",stdout); #endif init(); solve(); #ifndef ONLINE_JUDGE fclose(stdin); fclose(stdout); system("cow.out"); #endif return 0; }
标签:
原文地址:http://www.cnblogs.com/Sunnie69/p/5445773.html