[POJ2184] Cow Exhibition
题意:有n头牛,每头牛两个元素(s,t),选择若干头牛使∑s+∑t最大,且∑s、∑t非负
题解:
dp(带决策条件的状态)
状态:dp[j]表示s和为j时,t和的最大值
转移:dp[j+s[i]]=max{dp[j]+t[i]} (j>=0)
这样是不行的,因为s[i]会被重复转移,所以要把当前被转移的答案存到另一个数组里
tmp[j+s[i]]=max{dp[j]+t[i]}
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<algorithm> #include<cmath> #define ll long long using namespace std; int dp[100010],tmp[100010]; struct Node { int s,t; bool operator < (Node x) const { return s>x.s; } }p[110]; int gi() { int x=0,o=1; char ch=getchar(); while(ch!='-' && (ch<'0' || ch>'9')) ch=getchar(); if(ch=='-') o=-1,ch=getchar(); while(ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar(); return o*x; } int main() { int n=gi(),S=n*1000,ans=0,inf; for(int i=1; i<=n; i++) { p[i].s=gi(),p[i].t=gi(); } sort(p+1,p+n+1); memset(dp,-63,sizeof(dp)); inf=dp[0],dp[0]=0; for(int i=1; i<=n; i++) { for(int j=0; j<=S; j++) tmp[j]=dp[j]; for(int j=S; j>=0; j--) { if(dp[j]==inf) continue; if(j+p[i].s>=0) { tmp[j+p[i].s]=max(dp[j+p[i].s],dp[j]+p[i].t); } } for(int j=0; j<=S; j++) dp[j]=tmp[j]; } for(int i=0; i<=S; i++) { if(dp[i]<0) continue; ans=max(ans,dp[i]+i); } printf("%d", ans); return 0; }