11.1實驗2
阿新 • • 發佈:2020-11-02
洛谷 P1651 塔
題目描述
小明很喜歡擺積木,現在他正在玩的積木是由N個木塊組成的,他想用這些木塊搭出兩座高度相同的塔,一座塔的高度是搭建它的所有木塊的高度和,並且一座塔至少要用一個木塊。每個木塊只能用一次,也可以不用。目前已知每塊木塊的高度,小明想知道在最終兩個塔的高度相同的情況下,他所能搭的塔的最大高度是多少,你能幫助他嗎?
輸入格式
第一行為一個整數N,表示木塊個數。
第二行是N個整數,表示N塊木塊的高度。
【資料規模】
對於100%的資料,N≤50,每塊木塊的高度h滿足1≤h≤500000,所有木塊的高度總和≤500000。
輸出格式
僅一個整數,表示能搭建的塔的最大高度,若不能搭建兩座相同高度的塔,則輸出“-1”。
題解:
差值DP模板。
加了個滾動陣列。
嗖嗖快。
提示:滾動陣列要開大一些,否則容易RE。
程式碼:
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int maxn=5e5+5; int n,sum,ans=-1; int h[maxn]; int dp[3][maxn]; int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf("%d",&h[i]); sum+=h[i]; } memset(dp,-0x3f,sizeof(dp)); dp[0][0]=0; for(int i=1;i<=n;i++) for(int j=0;j<=sum;j++) { dp[i%2][j]=max(dp[(i-1)%2][j],dp[(i-1)%2][j+h[i]]); if(j>=h[i]) dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][j-h[i]]+h[i]); else dp[i%2][j]=max(dp[i%2][j],dp[(i-1)%2][h[i]-j]+j); } if(dp[n%2][0]>0) printf("%d",dp[n%2][0]); else puts("-1"); return 0; }