poj1160-Post Office(区间动规+四边形不等式优化)

来源:互联网 发布:阿里云服务器端口映射 编辑:程序博客网 时间:2024/05/02 14:12
#include <iostream>#include <cstring>#include <algorithm>using namespace std;int n, m;int x[305];int f[35][305], p[400][305];int w[305][305];int Left[305][305], Right[305][305];//left[i][j]表示第i+1,i+2,...,j个村庄到第i个村庄的距离和// right[i][j]表示第i-1,i-2,...,j个村庄到第i个村庄的距离和struct poj1160 {/*[问题描述]:有n个村庄,其位置分别为x[1],x[2],...,x[n],*从这n个村庄中选出m个设立邮局,要求每个村庄到它最近邮局的距离之和最小*//*[解题思路]:f[i][j]表示在前j个村庄设i个邮局所得到的最小距离和,则f[i][j]=min(f[i-1][k]+w[k+1][j]),*w[k+1][j]表示在第k+1到第j个村庄设一个邮局的最小距离和,显然应该将唯一的邮局设在中间那个村庄.*令p[i][j]表示使得f[i][j]最小的那个k,根据四边形不等式优化可知p[i-1][j]<=p[i][j]<=p[i][j+1]*/void work() {cin >> n >> m;for (int i = 1; i <= n; i++)cin >> x[i];for (int i = 1; i <= n; i++) {Left[i][i] = 0;for (int j = i + 1; j <= n; j++)Left[i][j] = Left[i][j - 1] + x[j] - x[i];}for (int i = n; i >= 1; i--) {Right[i][i] = 0;for (int j = i - 1; j >= 1; j--)Right[i][j] = Right[i][j + 1] + x[i] - x[j];}memset(w, 0, sizeof(w));for (int i = 1; i <= n; i++) {for (int j = i + 1; j <= n; j++) {int tmp = (j + i) >> 1;if ((j - i) % 2 == 0)w[i][j] = Right[tmp][i] + Left[tmp][j];elsew[i][j] = min(Right[tmp][i] + Left[tmp][j], Right[tmp + 1][i] + Left[tmp + 1][j]);}}for (int i = 1; i <= n; i++) {f[1][i] = w[1][i];//p[1][i] = (i + 1) >> 1;//p[i][n + 1] = n;p[i][i] = i - 1;}for (int i = 2; i <= m; i++) {p[i][n + 1] = n - 1;for (int j = n; j >= i; j--) {f[i][j] = 1 << 30;for (int k = p[i - 1][j]; k <= p[i][j + 1]; k++) {if (f[i][j] > f[i - 1][k] + w[k + 1][j]) {f[i][j] = f[i - 1][k] + w[k + 1][j];p[i][j] = k;}}}}cout << f[m][n] << endl;}};int main(){poj1160 solution;solution.work();return 0;}

1 0
原创粉丝点击