poj 2184 Cow Exhibition

题目大意:给定一组成员,每个成员包含ts,tf两个值,两者都有负值,要你从这组成员中选出一些成员,保证ts的和不为负数,tf的和也不为负数,并且ts的和与tf的和最大。

解题思路:背包问题,把ts看做容量,tf看做价值,由于有负值,所以把最小负值平移到原点。

当ts为正数时,由于要利用到上次求到的结果,并且每个物品只能选一次,所以,按照从大到小扫描

当ts为负值时,从小到大扫描

#include 
#include 
#include 
#include 
using namespace std;

struct node
{
	int ts, tf;
};

const int maxn = 110;
const int inf = 200000;

int n, ts, tf;
node cows[maxn];
int dp[inf + 10];

int main()
{
	
	while(scanf("%d", &n) != EOF)
	{
		for(int i = 0; i <= inf; i++)
			dp[i] = INT_MIN;
		for(int i = 1; i <= n; i++)
		{
			scanf("%d %d", &cows[i].ts, &cows[i].tf);
		}
		dp[inf / 2] = 0;
		for(int i = 1; i <= n ; i++)
		{
			if(cows[i].ts >= 0)
			{
				for(int j = inf; j >= cows[i].ts; j--)
				{
					if(dp[j - cows[i].ts] != INT_MIN)
						dp[j] = max(dp[j], dp[j - cows[i].ts] + cows[i].tf);
				}
			}
			else
			{
				for(int j = cows[i].ts; j <= inf + cows[i].ts; j++)
				{
					if(dp[j - cows[i].ts] != INT_MIN)
						dp[j] = max(dp[j], dp[j - cows[i].ts] + cows[i].tf);
				}
			}
		}
		int ans = INT_MIN;
		int val = inf / 2;
		for(int i = val; i <= inf; i++)
		{
			if(dp[i] >= 0)
				ans = max(ans, dp[i] + i - val);
		}
		printf("%d\n", ans);
	}
	
	return 0;
}


你可能感兴趣的:(背包问题,ACM,动态规划)