您的位置:首页 > 其它

poj1160 Post Office

2013-04-19 15:07 190 查看
输入:

10 5
1 2 3 6 7 9 11 22 44 50

意为有10个小村,有5个邮局,放置邮局使得所有小村到最近的邮局的距离之和最小

小村的坐标为1,2,3,6,7,9,11,22,44,50

定义状态:

dp[i][j]表示[0,i]这i+1个小村放置j个邮局的最小指

状态转移:

dp[i][j]=dp[k][j-1]+L[k+1][i] L[i][j]表示[i,j]放置一个邮局时的最小指,0<=k<i

代码:

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[330][40];//dp[i][j]表示0,,,i个村庄j个邮局的最小值
int L[330][330];//L[i][j]表示[i,j]一个邮局的最小值
int village[330];
void Run(int i,int j)
{
int mid=(i+j)/2;
L[i][j]=0;
for(int k=i;k<=j;k++)
{
L[i][j]+=abs(village[mid]-village[k]);
}
}
void RunDp(int i,int j)//求dp[i][j]   [0,i]
{
if(j==1)
{
if(L[0][i]==-1)
{
Run(0,i);
}
dp[i][j]=L[0][i];
return;
}
if(i==0)
{
if(j>=1)
{
dp[i][j]=0;
}
return;
}
for(int k=0;k<i;k++)
{
if(dp[k][j-1]==-1)
{
if(k==0&&j==1)
{
k=0;
}
RunDp(k,j-1);
}
if(L[k+1][i]==-1)
{
Run(k+1,i);
}
if(dp[i][j]==-1||dp[i][j]>dp[k][j-1]+L[k+1][i])
{
dp[i][j]=dp[k][j-1]+L[k+1][i];
}
}
}
int main()
{
int V,P;
while(~scanf("%d%d",&V,&P))
{
memset(dp,-1,sizeof(dp));
memset(L,-1,sizeof(L));
for(int i=0;i<V;i++)
{
scanf("%d",&village[i]);
}
RunDp(V-1,P);
printf("%d\n",dp[V-1][P]);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: