zoukankan      html  css  js  c++  java
  • USACO08FEB Making the Grade G

    题目链接

    Solution

    可以发现当前状态只与当前的位置和当前修改后的值有关。如果按照单调不降序列 dp:

    (f_{i,j}) 表示当前走到第 (i) 条路,修改后的值是 (j) 能得到的最小代价。那么有一个简单的转移方程式:

    [f_{i,j}=max(f_{i-1,k})+|a_i-j|(k≤j) ]

    再一看数据范围:(a_i≤10^9)...

    考虑一个性质:因为每个位置进行 (1) 单位的修改代价都是一样的,那么每个数修改后的值只可能是原数列中存在的值。根据这一点,可以对数列进行离散化,能成功地把空间复杂度压缩到了 (O(n^2))

    现在 dp 的时间复杂度依然是 (O(n^3)),有一个简单的优化,就是对 (i) 记一个前缀最大值 (g_{i,j})

    [g_{i,j}=max(f_{i,k}) (k≤j) ]

    它的转移方程式是这样的:

    [g_{i,j}=max(g_{i,j-1},f_{i,j}) ]

    这样做之后时间复杂度也变成了 (O(n^2))

    不上升序列就把 (a_i) 反过来再 dp 一遍。

    Code

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #define LL long long
    using namespace std;
    
    const int N = 2333;
    LL n, tmp, ans = 1e18, a[N], b[N], c[N], f[N][N], g[N][N];
    
    void dp()
    {
        memset(f, 0x7f7f7f, sizeof(f));
        memset(g, 0x7f7f7f, sizeof(g));
        for(int i = 1; i <= tmp; i++) f[0][i] = g[0][i] = 0;
        for(int i = 1; i <= n; i++)
        {
            for(int j = 1; j <= tmp; j++)
                f[i][j] = min(f[i][j], g[i - 1][j] + abs(b[a[i]] - b[j]));
            for(int j = 1; j <= tmp; j++)
                g[i][j] = min(f[i][j], g[i][j - 1]);
        }
        for(int i = 1; i <= tmp; i++) ans = min(ans, f[n][i]);
        return ;
    }
    
    int main()
    {
        scanf("%lld", &n);
        for(int i = 1; i <= n; i++)
            scanf("%lld", &a[i]), b[i] = a[i];
        sort(b + 1, b + n + 1);
        tmp = unique(b + 1, b + n + 1) - b - 1;
        for(int i = 1; i <= n; i++)
            a[i] = lower_bound(b + 1, b + tmp + 1, a[i]) - b;
        for(int i = 1; i <= n; i++) c[i] = a[i];
        dp();
        for(int i = 1; i <= n; i++) a[i] = c[n - i + 1];
        dp();
        printf("%lld", ans);
        return 0;
    }
    
  • 相关阅读:
    信息安全系统设计基础第九周学习总结
    信息安全系统设计基础第八周期中总结
    信息安全系统设计基础第七周学习总结
    深入理解计算机系统第六章家庭作业之6.35 6.36
    深入理解计算机系统第二、三章家庭作业之2.64 2.65 3.66 3.68
    信息安全系统设计基础第六周学习总结
    信息安全系统设计基础第五周学习总结
    JAVA 之 多态 抽象 接口
    JAVA 之 继承
    java.lang 类String
  • 原文地址:https://www.cnblogs.com/Andy-park/p/13820453.html
Copyright © 2011-2022 走看看