• POJ 3666 Making the Grade(二维DP)


    题目链接:http://poj.org/problem?id=3666

    题目大意:
    给出长度为n的整数数列,每次可以将一个数加1或者减1,最少要多少次可以将其变成单调不降或者单调不增(题目BUG,只能求单调不降).
    解题思路:
    有一个结论,每次将数字X改成Y时,Y一定是出现过的,所以可以用哈希减小数据范围。
    因为只用求单调不降,所以设dp[i][j]表示将1~i变为不降序列,且把第i个数改为第Hash[j]的最小花费 .
    可以得到状态转移方程dp[i][j]=min(dp[i-1][1~j])+abs(Hash[j]-a[i])

    代码

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #define LL long long
    using namespace std;
    const int N=2e3+5;
    
    LL a[N],dp[N][N],Hash[N];//dp[i][j]表示将1~i变为不降序列,且把第i个数改为第Hash[j]的最小花费 
                             
    LL Abs(LL a){
        return a>=0?a:-a;
    }
    
    int main(){
        int n;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i];
            Hash[i]=a[i];
        }
        sort(Hash+1,Hash+1+n);
        int cnt=unique(Hash+1,Hash+1+n)-Hash;
        
        for(int j=1;j<cnt;j++){
            dp[1][j]=Abs(Hash[j]-a[1]);
        }
        for(int i=2;i<=n;i++){
            LL tmp=1e18;
            for(int j=1;j<cnt;j++){
                tmp=min(tmp,dp[i-1][j]);
                dp[i][j]=Abs(Hash[j]-a[i]);
                dp[i][j]+=tmp;
            }
        }
        LL ans=1e18;
        for(int j=1;j<cnt;j++)
            ans=min(ans,dp[n][j]); 
        cout<<ans<<endl;
        return 0;
    }
  • 相关阅读:

    使用docker构建fastdfs
    docker测试
    java测试远程调试(转载)
    mac上运行mongodb-community
    mac上zookeeper服务开启,kafka开启
    idea注册配置
    java-集合
    selenium+phantomjs爬取bilibili
    [转载] Python数据类型知识点全解
  • 原文地址:https://www.cnblogs.com/fu3638/p/9892242.html
Copyright © 2020-2023  润新知