poj 1160 Post Office & SCAU 07校赛10320 Post Office ( dp )
来源:互联网 发布:无锡乐知英语 编辑:程序博客网 时间:2024/06/05 05:03
题意:
给出在同一直线上的v个村庄的坐标,要求建立p个邮局,使得所有村庄与离他最近的邮局的距离之和最小
参考别人的题解做的:
https://www.chenyajun.com/2010/05/27/4958
首先开一个二维数组cost,cost[i][j]表示在第i个到第j个村庄这一区间上建立 “一个”邮局时该区间上各个村庄到邮局的距离之和可以证明在(i+j)/2处建立邮局可使该区间距离之和最小(证法。。。)于是二层循环求解每个cost[i][j]再开一个二维数组res,res[i][j]表示前j个村庄建立i个邮局时的最小距离很明显有res[1][j]=cost[1][j] (1<=j<=v)然后是状态转移res[i][j](2<=i<=v,i<=j<=v) =min{ res[i-1][k] +cost[k+1][j] } (i-1<=k<=j)即“前j个村庄建立i个邮局的最小距离”等于 (对于所有合法的k){“前k个村庄建立i-1个邮局的最小距离”+ “第k+1个到第j个村庄建立“一个”邮局的最小距离”}中的最小值
#include <cstdio>const int N=305,INF=1e9+7;int cost[N][N],res[N][N],dis[N];int main(){ int v,p,mid,min; while(scanf("%d%d",&v,&p)>0) { for(int i=1;i<=v;i++) scanf("%d",dis+i); for(int i=1;i<=v;i++) for(int j=1;j<=v;j++) { mid=(i+j)/2; cost[i][j]=0; for(int k=i;k<mid;k++) cost[i][j]+=dis[mid]-dis[k]; for(int k=mid+1;k<=j;k++) cost[i][j]+=dis[k]-dis[mid]; } for(int i=1;i<=v;i++) res[1][i]=cost[1][i]; for(int i=2;i<=p;i++) for(int j=i;j<=v;j++) { min=INF; for(int k=i-1;k<j;k++) if(res[i-1][k]+cost[k+1][j]<min) min=res[i-1][k]+cost[k+1][j]; res[i][j]=min; } printf("%d\n",res[p][v]); }}
然后是SCAU_OJ 07年校赛
10320 Post Office时间限制:1000MS 内存限制:65535K提交次数:0 通过次数:0题型: 编程题 语言: 无限制DescriptionThere is a straight highway with villages alongside the highway. The highway is represented as an integer axis, and the position of each village is identified with a single integer coordinate. There are no two villages in the same position. The distance between two positions is the absolute value of the difference of their integer coordinates. Post offices will be built in some, but not necessarily all of the villages. A village and the post office in it have the same position.For building the post offices, their positions should be chosen so that the total sum of all distances between each village and its nearest post office is minimum. But there is another rule that for each village the nearest post office to it shouldn't exceed the distance of demand. Further more, the distance of demand for each village is different.You are to write a program which, given the positions of the villages, the distance of each village's demand and the number of post offices, computes the least possible sum of all distances between each village and its nearest post office. 输入格式Your program is to read from standard input. The first line contains two integers: the first is the number of villages V, 1 <= V <= 300, and the second is the number of post offices P, 1 <= P <= 30, P <= V. The second line contains V integers in increasing order. These V integers are the positions of the villages. For each position X it holds that 1 <= X <= 10000. The third line contains V integers. These V integers are the distance of demand. For each distance Y it holds that 1 <= Y <= 10000.输出格式The first line contains one integer S, which is the sum of all distances between each village and its nearest post office. If can't build post offices to satisfy the demand of all villages, output -1.输入样例10 51 2 3 6 7 9 11 22 44 5050 50 50 0 0 0 50 50 50 50输出样例20提示The five coordinates of the post offices are 6, 7, 9, 22, 50. The total sum of all distances is 20.作者admin
描述和poj基本一致,只是多了每个村庄都有一个与邮局的限制距离,在预处理和状态转移的时候进行判断即可
#include <cstdio>const int N=305,INF=1e9+7;int cost[N][N],res[N][N],dis[N],dem[N];int main(){ int v,p,mid,min,tmp,sum; while(scanf("%d%d",&v,&p)>0) { for(int i=1;i<=v;i++) scanf("%d",dis+i); for(int i=1;i<=v;i++) scanf("%d",dem+i); for(int i=1;i<=v;i++) for(int j=1;j<=v;j++) {// mid=(i+j)/2;// cost[i][j]=0;// for(int k=i;k<mid;k++)// cost[i][j]+=dis[mid]-dis[k];// for(int k=mid+1;k<=j;k++)// cost[i][j]+=dis[k]-dis[mid]; min=INF; for(mid=i;mid<=j;mid++) { sum=0; int k; for(k=i;k<mid;k++) { tmp=dis[mid]-dis[k]; if(tmp<=dem[k]) sum+=tmp; else break; } if(k<mid) continue; for(k=mid+1;k<=j;k++) { tmp=dis[k]-dis[mid]; if(tmp<=dem[k]) sum+=tmp; else break; } if(k<=j) continue; if(sum<min) min=sum; } if(min==INF) cost[i][j]=-1; else cost[i][j]=min; } for(int i=1;i<=v;i++) res[1][i]=cost[1][i]; for(int i=2;i<=p;i++) for(int j=i;j<=v;j++) { min=INF; for(int k=i-1;k<j;k++) if(res[i-1][k]!=-1&&cost[k+1][j]!=-1) if(res[i-1][k]+cost[k+1][j]<min) min=res[i-1][k]+cost[k+1][j]; if(min==INF) res[i][j]=-1; else res[i][j]=min; } printf("%d\n",res[p][v]); }}
- poj 1160 Post Office & SCAU 07校赛10320 Post Office ( dp )
- poj-1160 post office (dp)
- Post Office - POJ 1160 dp
- 【DP】 POJ 1160 Post Office
- POJ 1160 Post Office DP
- POJ 1160 Post Office (DP)
- poj 1160 post office------DP
- POJ 1160 Post Office(DP)
- poj - 1160 - Post Office(dp)
- poj 1160 Post Office(DP)
- poj 1160 Post Office(dp)
- POJ 1160 Post Office(经典DP)
- POJ 1160 Post Office(dp)
- POJ 1160 Post Office(dp)
- POJ 1160 Post Office(经典DP)
- poj 1160 Post Office(DP-简单DP)
- poj 1160 Post Office(DP简单题)
- POJ 1160 Post Office (经典dp)
- g++ error: no matching function
- 6. 重构之前
- python crawler0723.py
- Linux安装系统注意事项及系统初始化
- nk.bin和nk.nb0文件格式分析
- poj 1160 Post Office & SCAU 07校赛10320 Post Office ( dp )
- linux下c连接mysql
- 数据库命名规则
- ORACLE使用PL/SQL做条件调试
- 百度地图使用
- 静态链接与动态链接
- string类的方法总结
- Solution to Printing Neatly Problem
- C#学习笔记01:基本数据类型