P2340 [USACO03FALL] Cow Exhibition G
很典型的背包问题。要求 IQ 与 EQ 和的最大值,并保证 IQ EQ 和均大于 0,易知 dp,IQ 和 EQ 均大于 0 的条件可先不管,最后在合法区间统计答案即可。
考虑如何求 IQ 与 EQ 和的最大值,并且知道 IQ 与 EQ 分别的和。每头奶牛只有选和不选两种状态,设 f i f_i fi 表示 IQ 和为 i i i 时 EQ 和的最大值,相当于以 IQ 为 w i w_i wi,EQ 为 v i v_i vi 的 01 背包,易得状态转移方程式: f j = max ( f j , f j − w [ i ] + v i ) f_j=\max (f_j,f_{j-w[i]}+v_i) fj=max(fj,fj−w[i]+vi) ,答案即为 max ( f i + i ) \max(f_{i}+i) max(fi+i)。
注意到 w i w_i wi v i v_i vi 可能为负,转移时当 w i < 0 w_i<0 wi<0, j j j 从小到大转移。对于 v i v_i vi,只需将 f i f_i fi 向右平移 400000 400000 400000,答案记得改为 max 4 e 5 ≤ i ≤ 8 e 5 ( f i + i − 400000 ) \max\limits_{4e5\le i\le8e5}(f_i+i-400000) 4e5≤i≤8e5max(fi+i−400000)。
时间复杂度 O ( 8 e 5 n ) O(8e5\ n) O(8e5 n)。
#include<bits/stdc++.h>
using namespace std;
int n,a[405],b[405],f[800005];
int main(){scanf("%d",&n);for(int i=1;i<=n;i++) scanf("%d%d",a+i,b+i);memset(f,-0x3f,sizeof(f));f[400000]=0;for(int i=1;i<=n;i++){if(a[i]>0) for(int j=800000;j>=a[i];j--) f[j]=max(f[j],f[j-a[i]]+b[i]);else for(int j=0;j<=800000+a[i];j++) f[j]=max(f[j],f[j-a[i]]+b[i]);}int ans=0;for(int i=400000;i<=800000;i++) if(f[i]>=0) ans=max(ans,f[i]+i-400000);printf("%d",ans);return 0;
}
/*
start coding:08:43
finish debuging:08:52
*/