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]); }

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zyjjsf.html