P1651 塔 (dp)

原题链接:塔 - 洛谷

思路

求最大高度 -->想办法维护最大高度

int f[N][M]; //已经分配了第i个积木的时候高度差为j的两个塔中高的那个的高度

四种情况:

1.a[i]哪边都不放,高的塔最高值不变

2.a[i]放在矮的塔而且最后矮的塔还是矮的塔,高的塔值不变

3.a[i]放在高的塔,高的塔更高了,高的塔值加a[i]

4.a[i]放在矮的塔,矮的塔增加了a[i]之后比高的塔高了,这时高的塔的那个值要改变,加j

注意:

1)我们每次的j值都是高的减矮的差值,即我们不会让j值成为负数,所以四种情况得判断j与a[i]的关系,j + a[i]还是j - a[i]...

2)如果没有答案,f[n][0]的值不是-INF,而是0,塔的最大高度0,即没有放置任何木块

3)初始化f[][]为-INF,f[0][0] = 0

AC代码:

#include<bits/stdc++.h>
#define INF 0x3f3f3f3f
#define ll long long
#define PII pair<int,int>
#define rep(i, n) for (int i = 1; i <= (n); ++i)
#define rrep(i, n) for(int i = n; i >= 1; ++i)

using namespace std;

const double pi = acos(-1.0);

const int N = 55;
const int M = 5e5 + 10;
int a[N];
int f[N][M]; //已经分配了第i个积木的时候高度差为j的两个塔中高的那个的高度

int main()
{
    int n;
    scanf("%d", &n);
    int sum = 0;
    rep(i, n) scanf("%d", &a[i]), sum += a[i];
    memset(f, -0x3f, sizeof f);
    f[0][0] = 0;
    rep(i, n)
      for(int j = 0; j <= sum; j++){
        f[i][j] = max(f[i - 1][j], f[i - 1][j + a[i]]); //这两个都是高的那个塔的高度不改变
        if(j >= a[i]) f[i][j] = max(f[i][j], f[i - 1][j - a[i]] + a[i]);
        else f[i][j] = max(f[i][j], f[i - 1][a[i] - j] + j); //自己画一下图,这里对应的是把矮的那个加a[i]然后矮的那个变成了高的,与原来高的高j
      }
    if(f[n][0]) printf("%d", f[n][0]);
    else printf("-1");
    return 0;
}

 参考:题解 P2423 【双塔】 - 曾豪哥 的博客 - 洛谷博客

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值