您的位置:首页 > 其它

Post Office

2016-04-21 18:53 337 查看
http://poj.org/problem?id=1160这道题还是很难的(for me)看了题解才弄懂解题思路:动态规划分解出最优子结构 设dp[i][j]为i个邮局控制前j个村庄 例如i=2  j=4的时候其下有  (1,1)(2,3) (1,2)(2,2),(1,3)(2,1)这3种情况,我们取其中最小的那个。不难得出状态转移方程 dp[i][j]=min(dp[i-1][k]+cost[k+1][j])      i-1<=k<=j-1代码如下详细注释
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<stdlib.h>
#include<iomanip>
#include<list>
#include<deque>
#include<map>
#include <stdio.h>
#include <queue>

#define maxn 1000000+5
#define ull unsigned long long
#define ll long long
#define reP(i,n) for(i=1;i<=n;i++)
#define rep(i,n) for(i=0;i<n;i++)
#define cle(a) memset(a,0,sizeof(a))
#define mod 90001
#define PI 3.141592657

const ull inf = 1LL << 61;
const double eps=1e-5;

using namespace std;

bool cmp(int a,int b){
return a>b;
}
int cost[310][310];
int dp[32][310]; ///i个邮局控制j个村庄
int a[310];
///状态转移方程为dp[i][j]=min(dp[i-1][k]+cost[k+1][j]) i-1<=k<=j-1
int main()
{
//freopen("in.txt","r",stdin);
//freopen("out.txt","w",stdout);
int v,p;///v 村庄 p 邮局
while(cin>>v>>p)
{
cle(dp);
for(int i=1;i<=v;i++)
scanf("%d",&a[i]);
///构造cost[i][j] cost[i][j]表示i到j放一个邮局的最短距离和
for(int i=1;i<=v;i++)
for(int j=i;j<=v;j++)
{
cost[i][j]=0;
int mid=(i+j)/2;
for(int k=i;k<=j;k++)
{
cost[i][j]+=abs(a[k]-a[mid]);
}
}
///初始化 dp[i][j]邮局为1的情况
for(int i=1;i<=v;i++)
dp[1][i]=cost[1][i];

int Min;
for(int i=2;i<=p;i++)///枚举邮局
for(int j=i;j<=v;j++)///枚举村庄 从j=i开始和从j=1开始都行
{ Min=maxn;
for(int k=i-1;k<=j-1;k++)
{
Min=min(dp[i-1][k]+cost[k+1][j],Min);
}
dp[i][j]=Min;
}
cout<<dp[p][v]<<endl;
}
return 0;
}


 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: