题目背景
洛谷原题
奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对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,不过由于情商和变成负的了,所以是不允许的。
分析
这题可以看成一个01背包,对于每一头奶牛,可以有选或者不选两种。
先考虑如何表示状态。
dp[j] 前i只奶牛用for完成。
状态转移方程?
d p [ j ] = m a x ( d p [ j ] , d p [ j − s [ i ] ] + f [ i ] ) dp[j] = max(dp[j], dp[j−s[i]] + f[i]) dp[j]=max(dp[j],dp[j−s[i]]+f[i])
初始状态:
memset(dp, −0x3f, sizeof(dp)); //负无穷
dp[400000] = 0;
上代码
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int n,s[1001],f[1001],d[500001],ans;
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>s[i]>>f[i];
}
memset(d,-0x3f,sizeof(d));
d[100000]=0;
for(int i=1;i<=n;i++)
{
if(s[i]>=0)
{
for(int j=2*100000;j>=s[i];j--)
{
d[j]=max(d[j],d[j-s[i]]+f[i]);
}
}
else
{
for(int j=0;j<=2*100000+s[i];j++)
{
d[j]=max(d[j],d[j-s[i]]+f[i]);
}
}
}
for(int i=100000;i<=2*100000;i++)
{
if(d[i]>0)
{
ans=max(ans,i+d[i]-100000);
}
}
cout<<ans;
return 0;
}