-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathLawrenceOfArabia.cpp
133 lines (101 loc) · 2.6 KB
/
LawrenceOfArabia.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#include <bits/stdc++.h>
template<typename T> T gcd(T a, T b) {
if(!b) return a;
return gcd(b, a % b);
}
template<typename T> T lcm(T a, T b) {
return a * b / gcd(a, b);
}
template<typename T> void chmin(T& a, T b) { a = (a > b) ? b : a; }
template<typename T> void chmax(T& a, T b) { a = (a < b) ? b : a; }
int in() { int x; scanf("%d", &x); return x; }
using namespace std;
#ifdef ONLINE_JUDGE
#define debug(args...)
#else
#define debug(args...) fprintf(stderr,args)
#endif
typedef long long Int;
typedef unsigned long long uInt;
typedef unsigned uint;
const int MAXN = 1010;
const Int INF = 100100101001001000LL;
int N, M;
int P[MAXN];
Int dp[MAXN][MAXN];
Int memCost[MAXN][MAXN];
Int sum[MAXN];
Int cost(int l, int r) {
if (l == r) {
return 0LL;
} else {
Int& ans = memCost[l][r];
if (ans == -1) {
ans = 0LL;
for (int i = l; i < r; i++) {
Int pr = sum[r];
if (i >= 0) {
pr -= sum[i];
}
ans += P[i] * pr;
}
}
return ans;
}
}
Int func(int pos, int used) {
if (used == 0) {
return cost(pos, N);
} else if (pos == N + 1) {
return 0;
} else {
Int& ans = dp[pos][used];
if (ans == -1) {
ans = INF;
for (int i = pos; i < N; i++) {
chmin(ans, cost(pos, i) + func(i + 1, used - 1));
}
}
return ans;
}
}
void cost(int k, int l, int r, int optL, int optR) {
if (l > r) return;
int m = (l + r) / 2;
Int best = INF;
int id = optL;
for (int i = optL; i <= min(m, optR); i++) {
Int now = dp[i][k - 1] + cost(i + 1, m);
if (now < best) {
best = now;
id = i;
}
}
dp[m][k] = best;
cost(k, l, m - 1, optL, id);
cost(k, m + 1, r, id, optR);
}
int main(void) {
while (scanf("%d%d", &N, &M) == 2) {
if (N == 0 && M == 0) {
break;
}
for (int i = 1; i <= N; i++) {
cin >> P[i];
sum[i] = P[i] + sum[i - 1];
}
memset(memCost, -1, sizeof memCost);
for (int i = 1; i <= N; i++) {
dp[i][0] = cost(1, i);
}
for (int i = 1; i <= M; i++) {
cost(i, 1, N, 1, N);
}
Int ans = INF;
for (int i = 0; i <= M; i++) {
ans = min(ans, dp[N][i]);
}
printf("%lld\n", ans);
}
return 0;
}