zoukankan      html  css  js  c++  java
  • Making the Grade---poj3666(类似离散化+dp)

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

    题意是给出一组数,每个数代表当前位置的地面高度,问把路径修成非递增或者非递减,需要花费的最小代价?

    ///用dp[i][j]表示:前i个数构成的序列,这个序列最大值为j,dp[i][j]的值代表相应的cost。

    ///dp[i][j]=abs(j-w[i])+min(dp[i-1][k]);(k<=j)

    ///i-1构成的序列,最大值是k + (j-w[i])变成此步需要的花费

    因为要把路径修成非递减路径,所以a[j]>a[k],所以我们要三重循环来搞,时间复杂度O(n^3)。

    如果我们对原来数列进行复制排序的话,a[j]>a[k]就转化为了j>k,这样就成功的把时间复杂度从O(n^3)降为O(n^2)。

    空间复杂度也可以用滚动数组从O(n^2)变为O(n)。

    #include<stdio.h>
    #include<iostream>
    #include<string.h>
    #include<algorithm>
    using namespace std;
    #define N 2100
    #define INF 0x3f3f3f3f
    #define met(a) memset(a, 0, sizeof(a))
    //1061109567 0x3f3f3f3f
    //268435455  0xfffffff  本题用这个会错的;因为它不够大;害的我wa了那么多次-_-;
    int n, dp[N][N], a[N], b[N];
    
    int main()
    {
        while(scanf("%d", &n)!=EOF)
        {
            met(a); met(b);
            for(int i=1; i<=n; i++)
            {
                scanf("%d", &a[i]);
                b[i] = a[i];
            }
            sort(b+1, b+n+1);
            for(int i=1; i<=n; i++)
            {
                int Min = INF;
                for(int j=1; j<=n; j++)
                {
                    Min=min(Min, dp[i-1][j]);
                    dp[i][j] = Min + abs(a[i] - b[j]);
                }
            }
            int ans = INF;
            for(int i=1; i<=n; i++)
                ans=min(ans, dp[n][i]);
            printf("%d
    ", ans);
        }
        return 0;
    }
    

      

  • 相关阅读:
    2018年7月10日笔记
    2018年7月7日笔记
    2018年7月5日笔记
    2018年7月3日笔记
    sed 命令详解
    《软件构架实践》阅读笔记01
    《掌握需求过程》阅读笔记06
    《掌握需求过程》阅读笔记05
    第十二周进度条
    《掌握需求过程》阅读笔记04
  • 原文地址:https://www.cnblogs.com/zhengguiping--9876/p/4959114.html
Copyright © 2011-2022 走看看