题解 P1651 塔 (非常好的DP题!!!)

AC通道

非常好的 dp 题, 在复健运动中居然没想出来这么 dp。值得记录。详情看代码

#include <bits/stdc++.h> using namespace std; #define N 1000010 #define ll long long template <class T> inline void read(T& a){ T x = 0, s = 1; char c = getchar(); while(!isdigit(c)){ if(c == '-') s = -1; c = getchar(); } while(isdigit(c)){ x = x * 10 + (c ^ '0'); c = getchar(); } a = x * s; return ; } int dp[3][500001]; // 前 i 个木块,差为 j, 高的那个塔的最大高度 int n; int a[51]; int H; int main(){ // freopen("hh.txt", "r", stdin); // freopen("out.txt", "w", stdout); read(n); for(int i = 1; i <= n; i++) read(a[i]), H += a[i]; memset(dp, -0x3f, sizeof(dp)); dp[0][0] = 0; for(int i = 1; i <= n; i++){ for(int j = 0; j <= H; j++){ dp[i&1][j] = max(dp[(i&1)^1][j+a[i]], dp[(i&1)^1][j]); if(j - a[i] >= 0) dp[i&1][j] = max(dp[i&1][j], dp[(i&1)^1][j-a[i]] + a[i]); else dp[i&1][j] = max(dp[i&1][j], dp[(i&1)^1][abs(j-a[i])] + j); // 差值比 a[i] 小才能矮变高 } } // 如果放在高的那个 dp[i][j] = dp[i-1][j-a[i]] + a[i] // 如果不放 dp[i][j] = dp[i-1][j] // 放矮的那个,仍然矮: dp[i][j] = dp[i-1][j+a[i]] // 矮变高: dp[i][j] = dp[i-1][abs(j-a[i])] + j if(dp[n&1][0] > 0) cout << dp[n&1][0] << endl; else cout << -1 << endl; return 0; }
文章来源: https://www.cnblogs.com/wondering-world/p/16714149.html
All rights reserved ©雪之下,树之旁

__EOF__

本文作者雪之下,树之旁
本文链接https://www.cnblogs.com/wondering-world/p/16714149.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   雪之下,树之旁  阅读(16)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示