题目大意:给你一堆积木,选择其中的某些来组成两个相同高度的塔(对于某块积木,可以放在塔1,可以放在塔2,也可以都不放),问你最大组成的高度是多少?
用f[i][j]:表示左塔高度-右塔高度=j时。左塔高度+右塔高度的和的最大值。 f[i+1][s]=max(f[i][s], f[i+1][s]); //不放 f[i+1][s+a[i+1]]=max(f[i+1][s+a[i+1]], f[i][s]+a[i+1]); //放左 f[i+1][s-a[i+1]]=max(f[i+1][s-a[i+1]], f[i][s]+a[i+1]); //放右 #pragma GCC optimize(3, "Ofast", "inline") #include<bits/stdc++.h> using namespace std; int a[1005], f[100][20005], g[100][20005]; int main() { int n; scanf("%d", &n); for(int i=1; i<=n; i++){ scanf("%d", &a[i]); } memset(f, 0x8f, sizeof(f)); f[0][10000]=0; for(int i=0; i<n; i++){ for(int s=0; s<20005; s++){ if(f[i][s]>f[i+1][s]){ f[i+1][s]=f[i][s]; g[i+1][s]=0; } if(f[i][s]+a[i+1]>f[i+1][s+a[i+1]]){ f[i+1][s+a[i+1]]=f[i][s]+a[i+1]; g[i+1][s+a[i+1]]=1; } if(f[i][s]+a[i+1]>f[i+1][s-a[i+1]]){ f[i+1][s-a[i+1]]=f[i][s]+a[i+1]; g[i+1][s-a[i+1]]=2; } } } printf("%d\n", f[n][10000]/2); int s=10000; vector<int> v1, v2; while(n){ if(g[n][s]==0){ } else if(g[n][s]==1){ v1.push_back(a[n]); s-=a[n]; } else if(g[n][s]==2){ v2.push_back(a[n]); s+=a[n]; } n--; } printf("塔一:"); for(auto x: v1){ printf("%d ", x); } printf("\n"); printf("塔二:"); for(auto x: v2){ printf("%d ", x); } printf("\n"); return 0; }