C++ 纸牌 今日头条面试题

试题描述:

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

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

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

输入:

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

输出:

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

输入示例:

4
3 1
2 2
1 4
1 4

输出示例:

10

其他:

对于100%的数据,0<n<=100,1<x<=1e3,0<y<=1e6。

明显的dp,不能暴力枚举。

和0-1背包十分相似。

也是取和不取之间的关系。

注意:在两人不能为同一值时我们就要输出-1;

所以我们就可以把dp这个数组全部置为-1;

但是我们为了防止越界,所以我们要将一个很大的数组定为0.

这也就是我们之后的答案了(因为到了那里一定会有答案);

再说dp这个二维数组。dp[i][j]的i表示发到了第几张牌,j表示第一个人的积分。

在第二个人取牌时,我们就直接在j上减去一个x[i].就可以了,当他们一样是,j=0了

#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
using namespace std;
int n,m,dp[300][200000],x[100000],y[100000];
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++)
	{
		scanf("%d%d",&x[i],&y[i]);
	}
	memset(dp,-1,sizeof(dp));
	dp[0][100000]=0;
	for(int i=1;i<=n;i++)
	{
		for(int j=20000;j<=200000;j++)
		{
			dp[i][j]=max(dp[i-1][j+x[i]],dp[i-1][j-x[i]]);
			if(dp[i][j]!=-1)dp[i][j]+=y[i];
			if(dp[i][j]<dp[i-1][j])dp[i][j]=dp[i-1][j];
		}
	}
     printf("%d",dp[n][100000]);
}

 

posted @ 2018-08-17 11:23  FXY_ssf  阅读(1153)  评论(0编辑  收藏  举报