• card


     

    【问题描述】

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

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

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

    【输入】

    第一行n

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

    【输出】

    一行一个整数

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

    【输入输出样例】

    card.in

    card.out

    4

    3 1

    2 2

    1 4

    1 4

    10

    数据范围

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

    问题分(闲)析(聊):这道题是本蒟蒻上午考试的一道题,上午怎么想也想不出来。下午老师一讲思路就明白了,然后调题的时候一直在WA,刚写出来(在家,学校的内网登不上。还没测评,但应该是对了)。

     思路:这道题是一道动态规划,一张牌有三种情况,给A,给B,和谁都不给。怎么判断一样多呢?算一下数据范围,定个中点这道题的数据是100000,那就定55000,多开点(当然dp数组就要开110000了)。参考代码:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int dp[105][110005],n,x[105],s[100005],y[105];
     4 int main()
     5 {
     6     //freopen("card.in","r",stdin);
     7     //freopen("card.out","w",stdout);
     8     scanf("%d",&n);
     9     for(int i=1;i<=n;i++)
    10     {
    11         scanf("%d%d",&x[i],&y[i]);//输入个人值和团队值  
    12     }
    13     memset(dp,-1,sizeof(dp));// 都赋成-1,即没有意义的待转移状态 
    14     dp[0][55000]=0;//第零张牌,双方平衡,团队值也是零 
    15     for(int i=1;i<=n;i++)//第几张牌 
    16     {
    17         for(int j=6000;j<=110000;j++)
    18         {
    19             for(int k=-1;k<=1;k++)//枚举三种状态,-1(给A),0(谁都不给),1(给B) 
    20             {
    21                 if(k!=0&&dp[i-1][j+k*x[i]]!=-1)//这个待转移状态有意义吗 
    22                 {
    23                     dp[i][j]=max((dp[i-1][j+k*x[i]]+y[i]),dp[i][j]);//要求出最大值 
    24                 }
    25                 else if(k==0&&dp[i-1][j]!=-1) dp[i][j]=max(dp[i-1][j],dp[i][j]);//同上 
    26             }
    27         }
    28     }
    29     printf("%d",dp[n][55000]);//输出发完n张牌后双方个人值相等的团队最大值 
    30     return 0;//完美结束 
    31 }
  • 相关阅读:
    伪多项式时间 Pseudo-polynomial time
    Aho-Corasick算法
    写给十八岁以下的你
    网络流算法
    Java static关键字
    带有负权边的最短路径问题
    Miller_Rabin(米勒拉宾)素数测试
    关于同余与模运算的总结
    UVa1585
    UVa修改版02
  • 原文地址:https://www.cnblogs.com/jiuduSHENBENG/p/9489397.html
Copyright © 2020-2023  润新知