P1651 塔
Posted mysh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1651 塔相关的知识,希望对你有一定的参考价值。
题目描述
小明很喜欢摆积木,现在他正在玩的积木是由N个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块。每个木块只能用一次,也可以不用。目前已知每块木块的高度,小明想知道在最终两个塔的高度相同的情况下,他所能搭的塔的最大高度是多少,你能帮助他吗?
输入格式
第一行为一个整数N,表示木块个数。
第二行是N个整数,表示N块木块的高度。
【数据规模】
对于100%的数据,N≤50,每块木块的高度h满足1≤h≤500000,所有木块的高度总和≤500000。
输出格式
仅一个整数,表示能搭建的塔的最大高度,若不能搭建两座相同高度的塔,则输出“-1”。
输入输出样例
输入 #1
3 2 3 5
输出 #1
5
思路
用dp[i][j]表示前i块水晶搭建的双塔高度差值为j时较高的塔的高度
然后dp[i][j]存在四种情况,
这块水晶不放:dp[i][j] = dp[i - 1][j]
这块水晶放在矮的塔上面且依旧矮:dp[i][j] = dp[i - 1][j + a[i]]
这块水晶放在高的塔上:dp[i][j] = dp[i - 1][j - a[i]] + a[i]
这块水晶放在矮的塔上面且变成高塔:dp[i][j] = dp[i - 1][a[i] - j] + j
代码
#include<cmath> #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; const int N=55,M=500010; int dp[N][M]; int n,top,a[N]; int main () scanf("%d",&n); for(int i=1; i<=n; i++) scanf("%d",&a[i]); top+=a[i]; memset(dp,-2,sizeof(dp)); dp[0][0]=0; for(int i=1; i<=n; i++) for(int j=0; j<=top; j++) dp[i][j]=max(dp[i-1][j],dp[i-1][j+a[i]]); if(j>=a[i]) dp[i][j]=max(dp[i][j],dp[i-1][j-a[i]]+a[i]); else dp[i][j]=max(dp[i][j],dp[i-1][a[i]-j]+j); if(dp[n][0]==0) printf("-1"); else printf("%d\n",dp[n][0]); return 0;
以上是关于P1651 塔的主要内容,如果未能解决你的问题,请参考以下文章