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
*/
附上题目:
[USACO03FALL] Cow Exhibition G
题目背景
题目描述
奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对 N N N 头奶牛进行了面试,确定了每头奶牛的智商和情商。
贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。
输入格式
第一行:单个整数 N N N, 1 ≤ N ≤ 400 1 \le N \le 400 1≤N≤400。
第二行到第 N + 1 N+1 N+1 行:第 i + 1 i+1 i+1 行有两个整数: S i S_i Si 和 F i F_i Fi,表示第 i i i 头奶牛的智商和情商,− 1000 ≤ S i ; F i ≤ 1000 1000 \le S_i;F_i \le 1000 1000≤Si;Fi≤1000。
输出格式
输出单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出 0 0 0。
样例 #1
样例输入 #1
5
-5 7
8 -6
6 -3
2 1
-8 -5
样例输出 #1
8
提示
选择第一头,第三头,第四头奶牛,智商和为−5+6+2 = 3,情商和为7−3+1 = 5。再加
入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的