• card


    【问题描述】

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

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

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

    【输入】

    第一行n

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

    【输出】

    一行一个整数

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

    题解:这道题的dp方程是dp[i][j]=max(dp[i][j+a[i]*k],dp[i-1][j]);(k>=-1,k<=1)。因为k=-1时给b,k=1时给a,k=0时谁都不给,dp[i][j]表示取到第i个牌,a,b状态为j,j<100000时a小,j>100000时b小,j=100000时一样,初值:memeset(dp,-999999,sizeof(dp));dp[0][100000]=0;

    以下是代码:

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdlib>
    #include<cmath>
    #include<algorithm>
    using namespace std;
    int dp[105][200005];
    int a[105],b[105];
    int sum[105];
    int main()
    {
    	//freopen("card.in","r",stdin);
    	//freopen("card.out","w",stdout);
    	int n;
    	cin>>n;
    	for(int i=1;i<=n;i++)
    	{
    		scanf("%d%d",&a[i],&b[i]);
    		sum[i]=sum[i-1]+a[i];
    	}
    	memset(dp,-999999,sizeof(dp));
    	dp[0][100000]=0;
    	for(int i=1;i<=n;i++)
    	{
    		for(int j=100000-sum[i];j<=100000+sum[i];j++)
    		{
    			for(int k=-1;k<=1;k++)
    			{
    				if(k!=0)
    				{
                        dp[i][j+k*a[i]]=max(dp[i-1][j]+b[i],dp[i][j+k*a[i]]);
    				}
    				else
    				{
    					dp[i][j]=max(dp[i][j],dp[i-1][j]);
    				}
    			}
    		}      
    	}
    	cout<<dp[n][100000];
    	return 0;
    }
    

      

  • 相关阅读:
    systemctl命令
    linux下常用命令查看端口占用
    【PostgreSQL】存取jsonb
    tomcat内存溢出之PermGen space
    Spring事务传播机制
    java框架篇---spring aop两种配置方式
    Hibernate一对多实例
    Github 的系统内部都在用什么开源软件?
    这是一个关于软件开发的博客。
    JavaScript中数组的集合和映射
  • 原文地址:https://www.cnblogs.com/chen-1/p/9487699.html
Copyright © 2020-2023  润新知