POJ 1160 四边形不等式优化DP Post Office

d(i, j)表示用i个邮局覆盖前j个村庄所需的最小花费

则有状态转移方程:d(i, j) = min{ d(i-1, k) + w(k+1, j) }

其中w(i, j)的值是可以预处理出来的。

下面是四边形不等式优化的代码:

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <algorithm>
 4 #include <cstring>
 5 using namespace std;
 6 
 7 const int maxp = 30 + 10;
 8 const int maxv = 300 + 10;
 9 const int INF = 0x3f3f3f3f;
10 
11 int n, m;
12 
13 int a[maxv], sum[maxv];
14 int d[maxp][maxv], s[maxp][maxv];
15 
16 int w(int x, int y)
17 {
18     int t = (x + y) / 2;
19     return (t-x) * a[t]-(sum[t-1]-sum[x-1]) + (sum[y]-sum[t])-(y-t)*a[t];
20 }
21 
22 int main()
23 {
24     while(scanf("%d%d", &n, &m) == 2)
25     {
26         for(int i = 1; i <= n; i++) scanf("%d", a + i);
27         for(int i = 1; i <= n; i++) sum[i] = sum[i-1] + a[i];
28 
29         memset(d, 0x3f, sizeof(d));
30         for(int i = 1; i <= n; i++) { d[1][i] = w(1, i); s[1][i] = 0; }
31         for(int i = 2; i <= m; i++)
32         {
33             s[i][n+1] = n;
34             for(int j = n; j > i; j--)
35             {
36                 for(int k = s[i-1][j]; k <= s[i][j+1]; k++)
37                 {
38                     if(d[i-1][k] + w(k + 1, j) < d[i][j])
39                     {
40                         s[i][j] = k;
41                         d[i][j] = d[i-1][k] + w(k + 1, j);
42                     }
43                 }
44             }
45         }
46         printf("%d
", d[m][n]);
47     }
48 
49     return 0;
50 }
代码君
原文地址:https://www.cnblogs.com/AOQNRMGYXLMV/p/4694375.html