poj 1160 Post Office(DP)
2014-10-31 18:13
417 查看
首先要知道一个定理就是在一个区间内如果要设置一个邮局的话,最优位置一定是最中间的村子,而且如果村子数是偶数的话,中间的两个点是等价的。
知道了这个之后,就可以N^2处理出来任一一个区间中只设置一个邮局的最小距离和。cost[i][j]表示区间村子i到村子j。
dp[i][j]表示前i个村庄中设置j个邮局之后的最小距离和。
那么转移就是dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) (枚举k且k<j)
代码:
知道了这个之后,就可以N^2处理出来任一一个区间中只设置一个邮局的最小距离和。cost[i][j]表示区间村子i到村子j。
dp[i][j]表示前i个村庄中设置j个邮局之后的最小距离和。
那么转移就是dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) (枚举k且k<j)
代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int V,P; int Abs(int n){ return n>0?n:(-n); } int dp[40][305]; int p[305]; int cost[305][305]; int Get(int i,int j){ int mid=(i+j)/2; int sum=0; for(int k=i;k<=j;k++){ sum+=Abs(p[k]-p[mid]); } return sum; } int main(){ while(~scanf("%d%d",&V,&P)){ memset(dp,0x3f,sizeof(dp)); for(int i=1;i<=V;i++){ scanf("%d",&p[i]); } for(int i=1;i<=V;i++){ for(int j=i;j<=V;j++){ cost[i][j]=Get(i,j); //cout<<cost[i][j]<<endl; } } for(int i=1;i<=V;i++){ dp[1][i]=cost[1][i]; } for(int i=2;i<=P;i++){ for(int j=i;j<=V;j++){ for(int k=1;k<j;k++){ dp[i][j]=min(dp[i][j],dp[i-1][k]+cost[k+1][j]); } } } cout<<dp[P][V]<<endl; } return 0; }
相关文章推荐
- POJ 1160 Post Office (DP)
- POJ 1160 Post Office(抽象的二维DP)
- dp四边形优化 poj 1160 Post Office题解
- poj-1160 post office (dp)
- poj 1160 Post Office(DP简单题)
- POJ 1160 Post Office(经典DP)
- [DP优化] POJ 1160 Post Office
- POJ 1160 Post Office(四边形不等式优化DP)
- Poj-1160 Post Office(经典dp
- [DP 四边形不等式优化] POJ 1160 Post Office
- POJ 1160 Post Office(DP)
- 【DP】 POJ 1160 Post Office
- poj 1160 Post Office(四边形不等式优化dp)
- POJ 1160 Post Office(区间DP)
- POJ 1160 Post Office (二维DP)
- [dp] poj1160 Post office
- POJ 1160 Post Office(DP)
- POJ - 1160 Post Office(基础dp)
- poj 1160 Post Office (四边形不等式优化DP)
- POJ 1160 Post Office(经典DP)