zoukankan      html  css  js  c++  java
  • 线性dp+离散化 POJ

    https://vjudge.net/problem/POJ-3666

    题意:将一条路上的坑坑洼洼修补成单调的,求最小费用。

    分析:明显是线性dp,image.png

    如图,但 j 的数据太大, 就sort 一下用坐标表示达到离散化,并且每次找所有小于 j 的 k 的最小值,时间复杂度会变成三次方,所以要用Min 在 j 循环下记录最小值可以让复杂度变成平方。最后还可以用滚动数组节约空间。

    可以参考这篇博客https://www.cnblogs.com/vb4896/p/5877962.html 里面还有个nlogn 的方法

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define Abs(a) ((a)>=0?(a):-(a))
    using namespace std;
    
    typedef long long ll;
    const int maxn=2e3+9;
    int a[maxn],b[maxn];
    int dp[maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);        
    
        int Min;
        for(int i=1; i<=n; i++){
            Min=1e9+1;
            for(int j=1; j<=n; j++){
                Min = min( Min,dp[j] );
                dp[j] = Min +Abs( a[i]-b[j] );
            }
        }
    
        // for(int i=1; i<=n; i++){
        //     for(int j=1; j<=n; j++){
        //         printf("%d ",dp[i][j]);
        //     }
        //     puts("");
        // }
    
        int ans = dp[1];
        for(int i=2; i<=n; i++){
            ans = min(ans,dp[i]);    
        }
    
        printf("%d
    ",ans);
    }
    下面是不用滚动数组的
    //不用滚动数组的
    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define Abs(a) ((a)>=0?(a):-(a))
    using namespace std;
    
    typedef long long ll;
    const int maxn=2e3+9;
    int a[maxn],b[maxn];
    int dp[maxn][maxn];
    
    int main(){
        int n;
        scanf("%d",&n);
        for(int i=1; i<=n; i++){
            scanf("%d",&a[i]);
            b[i]=a[i];
        }
        sort(b+1,b+1+n);        
    
        int Min;
        for(int i=1; i<=n; i++){
            Min=1e9+1;
            for(int j=1; j<=n; j++){
                Min = min( Min,dp[i-1][j] );
                dp[i][j] = Min +Abs( a[i]-b[j] );
            }
        }
    
        // for(int i=1; i<=n; i++){
        //     for(int j=1; j<=n; j++){
        //         printf("%d ",dp[i][j]);
        //     }
        //     puts("");
        // }
    
        int ans = dp[n][1];
        for(int i=2; i<=n; i++){
            ans = min(ans,dp[n][i]);    
        }
    
        printf("%d
    ",ans);
    }
    View Code
  • 相关阅读:
    97. Interleaving String (String; DP)
    140. Word Break II (String; DP,DFS)
    139. Word Break (String; DP)
    120. Triangle(Array; DP)
    132. Palindrome Partitioning II (String; DP)
    91. Decode Ways (Array; DP)
    45. Jump Game II (Array; Two-Pointers,Greedy)
    LeetCode Excel Sheet Column Number
    LeetCode Factorial Trailing Zeroes
    LeetCode SQL: Second Highest Salary
  • 原文地址:https://www.cnblogs.com/-Zzz-/p/11417124.html
Copyright © 2011-2022 走看看