POJ 1160 Post Office(经典DP)
2015-10-30 17:48
459 查看
题意: 一些村庄被建立在一条笔直的高速公路边上,我们用一条坐标轴来描述这条高速公路,每一个村庄的坐标都是整数,没
有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每
一个村庄都必须建立邮局,邮局必须被建立在村庄里,因此它的坐标和它所在的村庄坐标相同。每个村庄使用离它最近的那个
邮局,建立这些邮局的原则是:所有村庄到各自所使用的邮局的距离总和最小。
思路:用d[i][j]表示从i村庄到j村庄建立一个邮局后各村庄到它的最小距离。显然应建立在中点。当村庄数位偶数个时,不难得到建立在中间偏左一个的村庄和偏右一个的村庄的距离和是一样的。所以可以O(n^2)预处理得到所有d值。dp[i][j]表示i个村庄j个邮局的最小距离和,扫描前i个村庄中间的点k。得到转移方程:
dp[i][j] = min(dp[i][j], dp[k][j-1] + d[k+1][i]),j <= k < i。
代码:
有两个村庄坐标相同。两个村庄间的距离,定义为它们的坐标值差的绝对值。我们需要在一些村庄建立邮局——当然,并不是每
一个村庄都必须建立邮局,邮局必须被建立在村庄里,因此它的坐标和它所在的村庄坐标相同。每个村庄使用离它最近的那个
邮局,建立这些邮局的原则是:所有村庄到各自所使用的邮局的距离总和最小。
思路:用d[i][j]表示从i村庄到j村庄建立一个邮局后各村庄到它的最小距离。显然应建立在中点。当村庄数位偶数个时,不难得到建立在中间偏左一个的村庄和偏右一个的村庄的距离和是一样的。所以可以O(n^2)预处理得到所有d值。dp[i][j]表示i个村庄j个邮局的最小距离和,扫描前i个村庄中间的点k。得到转移方程:
dp[i][j] = min(dp[i][j], dp[k][j-1] + d[k+1][i]),j <= k < i。
代码:
#include <algorithm> #include <iostream> #include <sstream> #include <cstring> #include <cstdio> #include <vector> #include <string> #include <queue> #include <stack> #include <cmath> #include <set> #include <map> using namespace std; typedef long long LL; #define mem(a, n) memset(a, n, sizeof(a)) #define ALL(v) v.begin(), v.end() #define si(a) scanf("%d", &a) #define sii(a, b) scanf("%d%d", &a, &b) #define siii(a, b, c) scanf("%d%d%d", &a, &b, &c) #define pb push_back #define eps 1e-8 const int inf = 0x3f3f3f3f, N = 3e2 + 5, MOD = 1e9 + 7; int T, cas = 0; int n, m; int x , d , dp ; int main(){ #ifdef LOCAL freopen("/Users/apple/input.txt", "r", stdin); // freopen("/Users/apple/out.txt", "w", stdout); #endif while(sii(n, m) != EOF) { for(int i = 1; i <= n; i ++) scanf("%d", &x[i]); mem(dp, 0x3f); mem(d, 0); for(int i = 1; i <= n; i ++) { for(int j = i + 1; j <= n; j ++) { d[i][j] = d[i][j-1] + x[j] - x[(i + j) / 2]; } } for(int i = 1; i <= n; i ++) dp[i][i] = 0, dp[i][1] = d[1][i]; for(int j = 2; j <= m; j ++) { for(int i = j + 1; i <= n ; i ++) { for(int k = j; k < i; k ++) { dp[i][j] = min(dp[i][j], dp[k][j-1] + d[k+1][i]); } } } printf("%d\n", dp [m]); } return 0; }
相关文章推荐
- 关于setImageState(int[] state, boolean merge)的解释以及使用方式
- maven 找不到jar包
- STM_HAL: assert_param 与 assert_failed函数
- 开源 java CMS - FreeCMS2.4字典管理
- Houdini Event Queue Full. Events being dropped:的解决方案
- Volley多次请求 RetryPolicy
- EasyUI combogrid 实现分页和数据模糊搜索
- centos安装LAMP
- Bundle Adjustment——光束平差法
- 移植tslib库出现ts_open: No such file or directory
- hiho一下 第六十九周 题目1 : HIHO Drinking Game 二分
- SQL Server2005主从复制实现
- Web前端开发学习1:静态网页
- ORACLE存储过程的应用(1流水号)
- ocilib 安裝配置
- 给定n个矩阵{A1, A2, …,An},其中,Ai与Ai+1是可乘的,计算这n个矩阵的连乘积。从中找出一种乘次数最少的计算次序(矩阵连乘最优顺序Java语言实现
- Intent传递对象的两种方法(Serializable,Parcelable) (转)
- section 模块页面切换代码
- 页面切换代码
- Java实现http服务器(一)