P1651 塔
作者:互联网
题目描述
小明很喜欢摆积木,现在他正在玩的积木是由N个木块组成的,他想用这些木块搭出两座高度相同的塔,一座塔的高度是搭建它的所有木块的高度和,并且一座塔至少要用一个木块。每个木块只能用一次,也可以不用。目前已知每块木块的高度,小明想知道在最终两个塔的高度相同的情况下,他所能搭的塔的最大高度是多少,你能帮助他吗?
输入格式
第一行为一个整数N,表示木块个数。
第二行是N个整数,表示N块木块的高度。
【数据规模】
对于100%的数据,N≤50,每块木块的高度h满足1≤h≤500000,所有木块的高度总和≤500000。
输出格式
仅一个整数,表示能搭建的塔的最大高度,若不能搭建两座相同高度的塔,则输出“-1”。
输入输出样例
输入 #13 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; }
标签:int,P1651,高度,木块,水晶,include,dp 来源: https://www.cnblogs.com/mysh/p/11441835.html