【问题描述】
小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;
}