-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathknuthOptimizationDp.cpp
More file actions
64 lines (59 loc) · 1.74 KB
/
Copy pathknuthOptimizationDp.cpp
File metadata and controls
64 lines (59 loc) · 1.74 KB
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
/*
********* Knuth Optimization of dp *********
Original Recurrence: dp[i][j] = mini < k < j{dp[i][k] + dp[k][j]} + C[i][j]
Sufficient Condition of Applicability: A[i, j - 1] ≤ A[i, j] ≤ A[i + 1, j]
Knuth Optimization is applicable if C[i][j] satisfies the following 2 conditions:
~quadrangle inequality: C[a][c]+C[b][d]<=C[a][d]+C[b][c], a<=b<=c<=d
~monotonicity: C[b][c]<=C[a][d], a<=b<=c<=d
*/
// https://www.spoj.com/problems/BRKSTRNG/
#include<bits/stdc++.h>
using namespace std;
#define FasterIO ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0)
const int MX=1000+5;
typedef long long ll;
int dp[MX][MX],knuths[MX][MX],cuts[MX];
int n,m;
void solve()
{
for(int l=0; l<=m; l++) // for l cuts where 0<=l<=m
{
for(int i=0, j=l+1; j<=m+1; i++, j++) // i=left cut, j=right cut
{
if(l==0)
{
dp[i][j]=0;
knuths[i][j]=j;
}
else
{
dp[i][j]=INT_MAX;
int cost=cuts[j]-cuts[i];
for(int k=knuths[i][j-1]; k<=knuths[i+1][j]; k++) // k=intermediate cut between i to j
{
if(dp[i][k]+dp[k][j]+cost < dp[i][j])
{
dp[i][j]=dp[i][k]+dp[k][j]+cost;
knuths[i][j]=k;
}
}
}
}
}
}
int main()
{
FasterIO;
while(cin>>n)
{
cin>>m;
cuts[0]=0; cuts[m+1]=n;
for(int i=1; i<=m; i++)
{
cin>>cuts[i];
}
solve();
cout<<dp[0][m+1]<<endl;
}
return 0;
}