codeforces 13C Sequence(排序,DP)

题意:
一个整数序列,每次操作可以对其中一个数加1或者减1。
求把这个序列变成非减序列所需的最少操作次数。
思路:
设原序列是A,目标序列是B
那么容易知道,B中的元素一定是A中元素的子集。
尝试用 f[i][j] 来表示,将前i个数变成非减序列,且最后一个元素的高度为 a[j],1<=j<=i 的最少操作
但是很快发现这个方程是错误的,因为j的取值范围应该是A中所有元素。
正确的方式是,将A中元素排序得到C
f[i][j] 表示 将前i个变成非减,最后元素不大于 c[j] 的最少操作
f[i][j]=min(f[i][j1],f[i1][j]+abs(a[i]c[j]))

// 空间优化至一维
LL solve() {
    rep(i, 1, n) b[i] = a[i];
    sort(b+1, b+1+n);
    int len = unique(b+1, b+1+n) - b-1;
    // 边界处理
    f[1] = abs (b[1] - a[1]);
    rep(i, 2, len) f[i] = min (f[i-1], abs(b[i]-a[1]));

    rep(i, 2, n) {
        f[1] = f[1] + abs(a[i] - b[1]);
        rep(j, 2, len) {
            f[j] = min (f[j-1], f[j] + abs (a[i] - b[j]));
        }
    }
    LL ans = f[1];
    rep(i, 1, len) ans = min (ans, f[i]);
    return ans;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值