【Luogu】P2340奶牛会展
突发奇想可以用f[i]表示智商和为i的时候情商最大是多少。这样就变成了一个背包问题。
最后更新答案的时候从0到最大背包容量遍历,最后答案是最大的i+f[i];
但是虽然答案只能从0到m里选,转移过程中是不能丢掉负数体积的。这是因为人家题目只说了要最后的智商和不能小于零,情商和不能小于零,没说中间不可以。
代码如下。
#include<cstdio> #include<cctype> #include<cstring> #include<algorithm> using namespace std; inline long long read(){ long long num=0,f=1; char ch=getchar(); while(!isdigit(ch)){ if(ch=='-') f=-1; ch=getchar(); } while(isdigit(ch)){ num=num*10+ch-'0'; ch=getchar(); } return num*f; } int f[1000000]; struct File{ int w,c; }que[1000]; int tot,ans; int main(){ int n=read(); for(int i=1;i<=n;++i){ que[i].w=read(); que[i].c=read(); if(que[i].w>0) tot+=que[i].w; } memset(f,-127/3,sizeof(f)); f[tot]=0; for(int i=1;i<=n;++i){ if(que[i].w>0) for(int j=tot<<1;j>=que[i].w;--j) f[j]=max(f[j],f[j-que[i].w]+que[i].c); else for(int j=0;j<=(tot<<1)-que[i].w;++j) f[j]=max(f[j],f[j-que[i].w]+que[i].c); } for(int i=tot;i<=tot<<1;++i){ if(f[i]>=0) ans=std::max(ans,f[i]+i-(tot)); } printf("%d",ans); return 0; }