• 【POJ】【1160】Post Office


    DP/四边形不等式


      邮局,经典的四边形不等式例题!

      关于四边形不等式的学习请看 赵爽论文《动态规划加速原理之四边形不等式》

      题目总结&题解:http://blog.csdn.net/shiwei408/article/details/8791011

      

      一个显而易见的结论是:对[l,r]这个区间内放一个邮局,放在中间的村子代价最小(类似中位数的感觉?。。。)

      这道题我一开始想动规方程的时候想成【石子合并】那种了……实际上dp[i][j]表示的是前 j 个村庄一共建了 i 个邮局的最小花费……

      然后就是以邮局数目为阶段转移……倒推可以减少可行状态,降低复杂度

     1 Source Code
     2 Problem: 1160        User: sdfzyhy
     3 Memory: 1108K        Time: 0MS
     4 Language: G++        Result: Accepted
     5 
     6     Source Code
     7 
     8     //POJ 1160
     9     #include<cmath>
    10     #include<vector>
    11     #include<cstdio>
    12     #include<cstring>
    13     #include<cstdlib>
    14     #include<iostream>
    15     #include<algorithm>
    16     #define rep(i,n) for(int i=0;i<n;++i)
    17     #define F(i,j,n) for(int i=j;i<=n;++i)
    18     #define D(i,j,n) for(int i=j;i>=n;--i)
    19     #define pb push_back
    20     using namespace std;
    21     int getint(){
    22         int v=0,sign=1; char ch=getchar();
    23         while(ch<'0'||ch>'9'){ if (ch=='-') sign=-1; ch=getchar();}
    24         while(ch>='0'&&ch<='9'){ v=v*10+ch-'0'; ch=getchar();}
    25         return v*=sign;
    26     }
    27     typedef long long LL;
    28     /******************tamplate*********************/
    29     const int N=301,INF=~0u>>2;
    30     int dp[31][N],s[31][N],w[N][N],a[N],n,m;
    31 
    32     int main(){
    33     #ifndef ONLINE_JUDGE
    34         freopen("1160.in","r",stdin);
    35         freopen("1160.out","w",stdout);
    36     #endif
    37         n=getint(); m=getint();
    38         F(i,1,n) a[i]=getint();
    39         
    40         F(i,1,n){
    41             w[i][i]=0;
    42             F(j,i+1,n) w[i][j]=w[i][j-1]+a[j]-a[(i+j)>>1];
    43         }
    44         F(i,1,n) F(j,1,m) dp[j][i]=INF;
    45         F(i,1,n){
    46             dp[1][i]=w[1][i];
    47             s[1][i]=0;
    48         }
    49         F(i,2,m){
    50             s[i][n+1]=n;
    51             D(j,n,i+1)
    52                 F(k,s[i-1][j],s[i][j+1])
    53                     if (dp[i-1][k]+w[k+1][j]<dp[i][j]){
    54                         s[i][j]=k;
    55                         dp[i][j]=dp[i-1][k]+w[k+1][j];
    56                     }
    57         }
    58         printf("%d
    ",dp[m][n]);
    59         return 0;
    60     }
    View Code
  • 相关阅读:
    在windows上使用win2000资源工具
    Apache与Tomcat整合
    web服务器和应用服务器概念比较
    linux定时删除N天前的文件(文件夹)
    程序员如何自我学习和成长?
    20210708总结
    Docker 常用命令!还有谁不会?
    Redis常用命令set
    laravel与thinkphp之间的区别与优缺点
    2021年7月总结
  • 原文地址:https://www.cnblogs.com/Tunix/p/4316919.html
Copyright © 2020-2023  润新知