题目背景
题目
奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对N 头奶牛进行了面试,确定了每头奶牛的智商和情商。
题目描述
贝西有权选择让哪些奶牛参加展览。由于负的智商或情商会造成负面效果,所以贝西不希望出展奶牛的智商之和小于零,或情商之和小于零。满足这两个条件下,她希望出展奶牛的智商与情商之和越大越好,请帮助贝西求出这个最大值。
输入格式
• 第一行:单个整数N,1 ≤ N ≤ 100
• 第二行到第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
分析:
由于对于每头牛 我们只能选或不选 就可以转换成一道 01 01 01背包题
把情商看做价值 智商看成体积即可
d p [ i ] [ j ] dp[i][j] dp[i][j]为前 i i i头奶牛 当智商为 j j j时的情商最大值
注意 智商值是可以为负数的 但我们的下标不能为负数 所以要整体后移 1000 ∗ 100 1000*100 1000∗100位
由于是求最大的智商 情商和 最后对于 d p [ n ] [ i ] + i dp[n][i]+i dp[n][i]+i取最大值即可
CODE:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#define reg register
using namespace std;
const int N=100005;
const int LIMIT=100000;
int n,s[105],f[105],dp[105][N],ans;
int main(){
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%d%d",&s[i],&f[i]);
memset(dp,-0x3f,sizeof(dp));
dp[0][0]=0;dp[0][LIMIT]=0;
for(reg int i=1;i<=n;i++)
for(reg int j=2*LIMIT;j>0;j--) //从-1000*100~1000*100 -> 0~2000*100
dp[i][j]=max(dp[i-1][j],dp[i-1][j-s[i]]+f[i]); //取或不取
for(int i=LIMIT;i<=2*LIMIT;i++) //在这个范围取最大
if(dp[n][i]>=0)
ans=max(ans,dp[n][i]+i-LIMIT); //记得原本值要减 100*1000
printf("%d",ans);
return 0;
}