card

【问题描述】

小a和小b玩一个游戏,有n张卡牌,每张上面有两个正整数x,y。

取一张牌时,个人积分增加x,团队积分增加y。

求小a,小b各取若干张牌,使得他们的个人积分相等。

【输入】

第一行n

接下来n行,每行两个整数x,y,用空格隔开。

【输出】

一行一个整数

表示小a的积分和小b的积分相等的时候,团队积分的最大值。

题解:这道题的dp方程是dp[i][j]=max(dp[i][j+a[i]*k],dp[i-1][j]);(k>=-1,k<=1)。因为k=-1时给b,k=1时给a,k=0时谁都不给,dp[i][j]表示取到第i个牌,a,b状态为j,j<100000时a小,j>100000时b小,j=100000时一样,初值:memeset(dp,-999999,sizeof(dp));dp[0][100000]=0;

以下是代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<algorithm>
using namespace std;
int dp[105][200005];
int a[105],b[105];
int sum[105];
int main()
{
	//freopen("card.in","r",stdin);
	//freopen("card.out","w",stdout);
	int n;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&a[i],&b[i]);
		sum[i]=sum[i-1]+a[i];
	}
	memset(dp,-999999,sizeof(dp));
	dp[0][100000]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=100000-sum[i];j<=100000+sum[i];j++)
		{
			for(int k=-1;k<=1;k++)
			{
				if(k!=0)
				{
                    dp[i][j+k*a[i]]=max(dp[i-1][j]+b[i],dp[i][j+k*a[i]]);
				}
				else
				{
					dp[i][j]=max(dp[i][j],dp[i-1][j]);
				}
			}
		}      
	}
	cout<<dp[n][100000];
	return 0;
}

  

原文地址:https://www.cnblogs.com/chen-1/p/9487699.html