纸牌

这道题。。。仿佛似曾相识

【题目描述】

小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 } 

讲真考试的时候我动规方程都出来了,初始值没定对。。。最后交了道深搜

 

在暴风雨中低着头,是为了不让雨水模糊风雨后眼中的彩虹。

 

posted @ 2018-08-17 10:55  Darkness_ly  阅读(242)  评论(0编辑  收藏  举报