poj 2184
阿新 • • 發佈:2019-02-15
最後的結果s無非屬於0~100000,列舉每個s相對應的f的最大值f,比較s+f得到最終的最大值。
求每個s相對應的f的最大值f用dp來求解,定義ans[]i[j]表示對於前i組數s的和為j的最大的f值,和01揹包類似。ans[i][j]=max(ans[i-1][j],ans[i-1][j-s[i]]+f[i]),狀態j原本範圍為-100000~100000,所以統一加100000,和0~200000一一對應,就可以用陣列下標表示了。
#include <iostream> #include <cstdio> #include <cstring> #include <queue> #include <algorithm> #include <cmath> #include <stack> #include <vector> #define LL long long #define myabs(x) ((x)>0?(x):(-(x))) using namespace std; const int inf=0x3f3f3f3f; const int maxn=100+10; const int maxm=2*100000+10; int ans[maxm]; int s[maxn],f[maxn]; int n; int main() { cin>>n; int i; for(i=1;i<=n;i++) scanf("%d%d",&s[i],&f[i]); memset(ans,-inf,sizeof(ans)); ans[100000]=0; int j,k; int m=2*100000; for(i=1;i<=n;i++) { if(s[i]>0) for(j=m;j>=s[i];j--) ans[j]=max(ans[j],ans[j-s[i]]+f[i]); else for(j=0;j<=(m+s[i]);j++) ans[j]=max(ans[j],ans[j-s[i]]+f[i]); } int re=-inf; for(i=100000;i<=200000;i++) if(ans[i]>=0) re=max(re,ans[i]+i-100000); if(re>-inf) printf("%d\n",re); else printf("0\n"); return 0; }