【2020.10.28 SSL模拟赛T2】[洛谷 P2340]SMRTFUN【01背包の变式】

题目背景

题目
奶牛想证明它们是聪明而风趣的。为此,贝西筹备了一个奶牛博览会,她已经对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 1000100
由于是求最大的智商 情商和 最后对于 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;
}

猜你喜欢

转载自blog.csdn.net/dgssl_xhy/article/details/109340304