POJ 1160 邮局

来源:互联网 发布:ios 新闻app源码 编辑:程序博客网 时间:2024/04/29 20:09

POJ 1160  邮局

状态:dp[i][j] 表示前j个村庄覆盖i个邮局所用最小值。

        cost[j+1][j+k]表示j+1..j+k个村庄覆盖一个邮局的最小值。

        其中j>=1

转移方程:dp[i+1][j+k]=min(dp[i-1][j]+cost[j+1][j+k]) 其中 j>=1;

#include<stdio.h>#include <string.h>int cost[302][302];int dp[302][302];int v[302];int kabs(int a){    return a>0?a:-a;}int main(){    int V,P,mid;    int tcase;    scanf("%d",&tcase);    while(tcase--){    scanf("%d %d",&V,&P);    for (int i=1;i<=V;i++)        scanf("%d",v+i);    //cost[i][j] 表示从i到j构建一个邮局距离之和    memset(dp,0,sizeof(dp));    memset(cost,0,sizeof(cost));    for (int i=1;i<=V;i++){        for (int j=i;j<=V;j++){            mid=(i+j)>>1;//中位数 奇数时取中间的 偶数时取中间两个前者            for (int k=i;k<=j;k++)                cost[i][j] +=kabs(v[mid]-v[k]);        }    }    //dp[i][j] 表示前i个邮局覆盖前j个村庄的最小代价    for (int i=1;i<=V;i++)        dp[1][i]=cost[1][i];    for (int i=2;i<=P;i++){        for (int j=1;j<=V;j++){            for (int k=1;k+j<=V;k++){                if(dp[i][j+k]>dp[i-1][j]+cost[j+1][j+k] || dp[i][j+k]==0)//update                    dp[i][j+k]=dp[i-1][j]+cost[j+1][j+k];            }        }    }    printf("%d\n",dp[P][V]);    }    return 0;}
注:本以为可以剪去部分内容,自己强加了一个条件,J>=I

但是提交后错误,因为多个邮局可以建在一个村庄。

0 0
原创粉丝点击