纸牌
这道题。。。仿佛似曾相识
【题目描述】
小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
这已经是第三道01背包了。。。我们老师好像和01背包干上了。
dp[i][j]=前i张卡个人积分的差值为j
dp[i][j]=>dp[i-1][j-cardx[i]]+cardy[i](第i张卡给a)]
=>dp[i-1][j+cardx[i]]+cardy[i](第i张卡给b)}这三种的最大值
=>dp[i-1][j](谁都不给) ]
由于会出现负值,所以我们把dp[0][60000]设定为真正的0
代码如下
1 #include<iostream> 2 #include<cstring> 3 using namespace std; 4 int cardx[10013],cardy[10013]; 5 int n; 6 int dp[113][120000]; 7 int main() 8 { 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++) 11 { 12 scanf("%d%d",&cardx[i],&cardy[i]); 13 } 14 memset(dp,-1,sizeof(dp)); 15 dp[0][60000]=0; 16 for(int i=1;i<=n;i++) 17 { 18 for(int j=0;j<=120000;j++) 19 { 20 if(dp[i-1][j-cardx[i]]!=-1) 21 { 22 dp[i][j]=max(dp[i-1][j-cardx[i]]+cardy[i],dp[i][j]); 23 } 24 if(dp[i-1][j+cardx[i]]!=-1) 25 { 26 dp[i][j]=max(dp[i][j],dp[i-1][j+cardx[i]]+cardy[i]); 27 } 28 dp[i][j]=max(dp[i][j],dp[i-1][j]); 29 } 30 } 31 printf("%d",dp[n][60000]); 32 }
讲真考试的时候我动规方程都出来了,初始值没定对。。。最后交了道深搜
在暴风雨中低着头,是为了不让雨水模糊风雨后眼中的彩虹。