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 }