zoukankan      html  css  js  c++  java
  • 【BZOJ 1592】[Usaco2008 Feb]Making the Grade 路面修整 dp优化之转移变状态

    我们感性可证离散(不离散没法做),于是我们就有了状态转移的思路(我们只考虑单不减另一个同理),f[i][j]到了第i块高度为j的最小话费,于是我们就可以发现f[i][j]=Min(f[i-1][k])+|a[i]-j|(k<=j),于是我们的思路就去了各种数据结构…….然后我们发现对于这些转移就是在记录小于等于,那么我们直接带状态里体现这一点就可以了,而不是在转移的时候,我们f[i][j]表示到了第i个点小于等于j的高度的最小花费,这样我们就n^2了。

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    #define N 2010
    using namespace std;
    inline int read()
    {
      register int sum=0;register char ch=getchar();
      while(ch<'0'||ch>'9')ch=getchar();
      while(ch>='0'&&ch<='9')sum=(sum<<1)+(sum<<3)+ch-'0',ch=getchar();
      return sum;
    }
    int a[N],f[N][N],ans,n,pos[N],len,Hash[N];
    int comp(const int x,const int y){
      return a[x]<a[y];
    }
    inline int Min(int x,int y){
      return x<y?x:y;
    }
    inline int Abs(int x){
      return x<0?-x:x;
    }
    inline int get_Min(){
      memset(f,0x7f,sizeof(f));register int ans=0x7fffffff;
      for(register int i=1;i<=len;i++)f[1][i]=Min(f[1][i-1],Abs(Hash[i]-Hash[a[1]]));
      for(register int i=2;i<=n;i++)
        for(register int j=1;j<=len;j++)
          f[i][j]=Min(f[i][j-1],f[i-1][j]+Abs(Hash[j]-Hash[a[i]]));
      for(register int i=1;i<=len;i++)ans=Min(ans,f[n][i]);
      return ans;
    }
    inline int get_Max(){
      memset(f,0x7f,sizeof(f));register int ans=0x7fffffff;
      for(register int i=1;i<=len;i++)f[1][i]=Min(f[1][i+1],Abs(Hash[i]-Hash[a[1]]));
      for(register int i=2;i<=n;i++)
        for(register int j=len;j>0;j--)
          f[i][j]=Min(f[i][j+1],f[i-1][j]+Abs(Hash[j]-Hash[a[i]]));
      for(register int i=1;i<=len;i++)ans=Min(ans,f[n][i]);
      return ans;
    }
    int main(){
      n=read();for(register int i=1;i<=n;i++)a[i]=read(),pos[i]=i;
      sort(pos+1,pos+n+1,comp);
      for(register int i=1;i<=n;i++)
        if(i==1||a[pos[i]]!=a[pos[i-1]])Hash[++len]=a[pos[i]],a[pos[i]]=len;
        else a[pos[i]]=len;
      printf("%d",Min(get_Min(),get_Max()));
    }
  • 相关阅读:
    pycharm 安装第三方库,出现错误: error: Microsoft Visual C++ 14.0 is required. Get it with "Microsoft Visual C++ Build Tools": http://landinghub.visual studio.com/visual-cpp-build-tools
    c# 开发常用小方法
    [LeetCode]28. 实现 strStr()
    [LeetCode]27. 移除元素
    [LeetCode]21. 合并两个有序链表
    [LeetCode]20. 有效的括号
    [LeetCode]14. 最长公共前缀
    [LeetCode]13. 罗马数字转整数
    [LeetCode]9. 回文数
    [LeetCode]2. 两数相加
  • 原文地址:https://www.cnblogs.com/TSHugh/p/7288914.html
Copyright © 2011-2022 走看看