Z2506 水晶塔加强版

题目描述

Description

给你N个数字,当然不是每个数字你均需要用到,现将这些数字分成两部份,然后分别统计其总和

现在希望这两个总和是一样大的,并且越大越好。

Format

Input

第一个数字𝑁N代表数字的个数.

接下来𝑁N个数代表每个数字.所有数字的总和不超过1000010000

𝑁N<=100

Output

其总和是相等的。问这个值最大能到多少?如果不能分成相等的两份就输出"Sorry"

Samples

输入数据 1

4 
11 11 11 11

Copy

输出数据 1

22

 思路

就两种情况,选与不选,选的话,还分成加给较矮的塔和较大的塔两种情况,注意一点,如果加给了矮塔,还得判断是否加上的值大于之前两塔的差,那么,两塔关系需转换一下,得分开来写。

如果加给矮塔:

1、加上的值大于之前两塔的差

dp[i][a[i]-j]=max(dp[i][a[i]-j],j+dp[i-1][j]);

2、加上的值小于之前两塔的差

dp[i][j-a[i]]=max(dp[i][j-a[i]],dp[i-1][j]+a[i]);

如果加给高塔:

dp[i][j+a[i]]=max(dp[i-1][j],dp[i][j+a[i]]);

代码

#include<bits/stdc++.h>
#define  rep(i,a,b) for(int i=a;i<=b;++i)
#define ll long long
using namespace std;
int n,a[2005],sum=0,dp[2005][11001];
int main()
{
	cin>>n;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		sum+=a[i];
	}
	memset(dp,-1,sizeof(dp));//全设为-1
	dp[0][0]=0;//dp存当前的更小塔的高度,初始化dp
	for(int i=1;i<=n;i++){
		for(int j=0;j<=sum/2;j++)//j表示当前两座塔的差,不可能超过总数的一半
		{
			if(dp[i-1][j]>=0){//表示有过这种情况,没有,就为-1
				dp[i][j]=max(dp[i][j],dp[i-1][j]);//不取的情况
				dp[i][j+a[i]]=max(dp[i-1][j],dp[i][j+a[i]]);//将高度加给较高塔的
				if(a[i]>j){//加给较矮塔的情况,如果加上的高度比差j大
					dp[i][a[i]-j]=max(dp[i][a[i]-j],j+dp[i-1][j]);
				}
				else{//如果加上的高度比差j小
					dp[i][j-a[i]]=max(dp[i][j-a[i]],dp[i-1][j]+a[i]);
				}
			}
		}
	}
	if(dp[n][0])cout<<dp[n][0];//答案在dp[n][0],如果它不等于-1,就输出
	else cout<<"Sorry";//反之
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值