题目描述
Description
给你N个数字,当然不是每个数字你均需要用到,现将这些数字分成两部份,然后分别统计其总和
现在希望这两个总和是一样大的,并且越大越好。
Format
Input
第一个数字𝑁N代表数字的个数.
接下来𝑁N个数代表每个数字.所有数字的总和不超过1000010000
𝑁N<=100
Output
其总和是相等的。问这个值最大能到多少?如果不能分成相等的两份就输出"Sorry"
Samples
输入数据 1
4 11 11 11 11Copy
输出数据 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;
}

261

被折叠的 条评论
为什么被折叠?



