POJ 1160 Post Office
来源:互联网 发布:英语6级口语考试知乎 编辑:程序博客网 时间:2024/06/06 14:22
题意:给定n(n<=300)个在一维坐标系下的村庄,想从中挑选m(m<=30)个作为邮局,使得每个村庄到最近的邮局的距离和最小。
题解:想到dp,因为dp的值和当前状态的最后一个post office的位置有关系,开始想到dp[i][j][k]代表在前i个村庄中选择j个post office最后一个post office在位置k的
最小花费,但是转移需要很大的时间复杂度,然后想dp[i][j]代表在前i个村庄中选择j个post office的最小花费,这样的话需要枚举最后一个office和倒数第二个
office的管辖分界线,同时需要预处理出来在[i , j]村庄内选一个office的最小花费,将office放到(i+j)/2的位置即可。
Sure原创,转载请注明出处。
#include <iostream>#include <cstdio>#include <memory.h>using namespace std;const int inf = 1 << 29;const int maxn = 302;const int maxm = 32;int pos[maxn],sum[maxn],dp[maxn][maxm],map[maxn][maxn];int m,n;inline int MIN(int a,int b){ return a < b ? a : b;}void read(){ sum[0] = 0; for(int i=1;i<=n;i++) { scanf("%d",&pos[i]); sum[i] = sum[i-1] + pos[i]; } return;}void make(){ for(int i=1;i<=n;i++) { map[i][i] = 0; for(int j=i+1;j<=n;j++) { int p = (i + j) / 2; int val = sum[j] + sum[i-1] - sum[p] * 2; if(((i + j) & 1) == 0) val += pos[p]; map[i][j] = map[j][i] = val; } } return;}void solve(){ for(int i=1;i<=n;i++) { dp[i][1] = map[1][i]; } for(int i=1;i<=n;i++) { for(int j=2;j<=m;j++) { dp[i][j] = dp[i][j-1]; for(int k=1;k<i;k++) { dp[i][j] = MIN(dp[i][j] , dp[k][j-1] + map[k+1][i]); } } } printf("%d\n",dp[n][m]); return;}int main(){ while(~scanf("%d %d",&n,&m)) { read(); make(); solve(); } return 0;}
- POJ 1160 Post Office
- poj 1160 Post Office
- POJ 1160 Post Office
- poj 1160 Post Office
- POJ 1160 Post Office
- POJ 1160 Post Office
- poj 1160 post office
- poj 1160Post Office
- POJ--1160--Post Office
- poj 1160 Post Office
- POJ 1160 Post Office
- POJ 1160 Post Office
- POJ-1160-Post Office
- poj 1160 Post Office
- POJ 1160 Post Office
- poj 1160 Post Office
- POJ 1160 Post Office
- POJ 1160 Post Office
- POJ 2060 最小路径覆盖
- html5文件学习笔记1
- C++笔记(1): 预处理/编译/汇编/链接
- ios 常见异常
- libcurl库
- POJ 1160 Post Office
- unsigned int 和double 转换中出现的问题
- C/C++的static成员
- Java多线程同步Synchronized使用分析
- linux下安装jdk+tomcat+eclipse+mysql
- 指针和引用以及迭代器入门
- src总结
- C++中的文件操作
- SQL文测试数据时,注意对0件的测试!!!【0件时,防止空指针异常!】