P2340 [USACO03FALL] Cow Exhibition G

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,fjw[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) 4e5i8e5max(fi+i400000)

时间复杂度 O ( 8 e 5   n ) O(8e5\ n) O(8e5 n)

#include
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 1N400

第二行到第 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 1000Si;Fi1000

输出格式

输出单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出 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,不过由于情商和变成负的了,所以是不允许的

你可能感兴趣的:(dp,题解,学习,c++,算法,开发语言)