【USACO】 奶牛会展
题目背景
奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行
了面试,确定了每头奶牛的智商和情商。
题目描述
贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。
输入输出格式
输入格式:• 第一行:单个整数N,1 ≤ N ≤ 400
• 第二行到第N + 1 行:第i + 1 行有两个整数:Si 和Fi,表示第i 头奶牛的智商和情商,−1000 ≤ Si; Fi ≤ 1000
输出格式:输出格式
• 单个整数:表示情商与智商和的最大值。贝西可以不让任何奶牛参加展览,如果这样做是最好的,输出0
输入输出样例
输入样例#1:
5 -5 7 8 -6 6 -3 2 1 -8 -5
输出样例#1:
8
说明
选择第一头,第三头,第四头奶牛,智商和为−5+6+2 = 3,情商和为7−3+1 = 5。再加
入第二号奶牛可使总和提升到10,不过由于情商和变成负的了,所以是不允许的
题解:
以情商为物品容量,智商为价值,做一波背包即可,数组要平移一段 最后统计max(F[i]+i)即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 const int N=105,M=100005; 8 int w[N],f[N],F[M*2]; 9 int main() 10 { 11 int n,m=0; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++){scanf("%d%d",&w[i],&f[i]);if(w[i]>0)m+=w[i];} 14 m*=2; 15 memset(F,-127/3,sizeof(F)); 16 F[m/2]=0; 17 for(int i=1;i<=n;i++) 18 { 19 if(w[i]>0) 20 for(int j=m;j>=w[i];j--)F[j]=max(F[j],F[j-w[i]]+f[i]); 21 else 22 for(int j=0;j<=m-w[i];j++)F[j]=max(F[j],F[j-w[i]]+f[i]); 23 } 24 int ans=0,k=m/2; 25 for(int i=0;i<=k;i++)if(F[i+k]>=0 && i+F[i+k]>ans)ans=i+F[i+k]; 26 printf("%d",ans); 27 return 0; 28 }