四边形优化资料: https://blog.csdn.net/noiau/article/details/72514812
题目链接 : postoffice已过: https://cn.vjudge.net/problem/POJ-1160
#include<iostream>
#define maxlen 2001+90
#define maxvalue 1000000000
int c[maxlen];
int cost[maxlen][maxlen];
long long dp[maxlen][maxlen];
int n, m;
int s[maxlen][maxlen];
void getInput()
{
scanf("%d %d", &n, &m);
for (int i = 0; i < n; ++i)
scanf("%d", &c[i]);
}
void initcost()
{
int i;
for (i = 0; i < n; ++i)
{
cost[i][i] = 0;
}
for (int i = 2; i <= n; ++i)
{
for (int j = 0; j + i - 1 < n; ++j)
{
cost[j][j + i - 1] = cost[j][j + i - 2] + c[j + i - 1] - c[(j + j + i - 1) / 2];
}
}
}
void process()
{
initcost();
int i, j, k;
//for (k = 2; k <= n; ++k)
//{
// for (i = 0; i<n-k+1; ++i)//i+k-1 < n
// {
// for (j = i; j < i+k-1; ++j)
// {
// if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
// dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
// }
// dp[i][i + k - 1] += w[i][i + k - 1];
// }
//}
int src_max = n - 1;
int dst_max = m - 1;
for (i = 0; i <= dst_max; ++i)
{
s[i][i] = i;
}
for (i = 0; i <= src_max; ++i)
cost[i + 1][i] = 10000 * 10000;
i = 0;
for (j = src_max; j >= 0; --j)
{
dp[i][j] = cost[0][j];
s[i][j] = 0;
}
for (i = 1; i <= dst_max; ++i)
{
for (j = src_max; j >= 0; --j)
{
dp[i][j] = 10000 * 10000;
}
}
int mymin;
for (i = 1; i <= dst_max; ++i)
{
s[i][src_max + 1] = src_max;
for (j = src_max; j >= i; --j)
{
for (k = s[i - 1][j]; k <= s[i][j + 1]; ++k)
{
if (dp[i][j] > dp[i - 1][k] + cost[k + 1][j])
{
dp[i][j] = dp[i - 1][k] + cost[k + 1][j];
s[i][j] = k;
}
}
}
}
}
//void process()
//{
// int i, j, k;
// for (i = 0; i < n; ++i)
// {
// for (j = 1; j<= n-i; ++j) //i+j-1<n
// {
// w[i][j] = w[i][j - 1] + c[j];
// }
// }
//
// //for (k = 2; k <= n; ++k)
// //{
// // for (i = 0; i<n-k+1; ++i)//i+k-1 < n
// // {
// // for (j = i; j < i+k-1; ++j)
// // {
// // if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
// // dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
// // }
// // dp[i][i + k - 1] += w[i][i + k - 1];
// // }
// //}
// for (i = 0; i < n; ++i)
// {
// s[i][i] = i;
// }
//
// for (k = 2; k <= n; ++k)
// {
// for (i = 0; i<n - k + 1; ++i)//i+k-1 < n
// {
// for (j = s[i][i + k - 2]; j <= s[i + 1][i + k - 1]; ++j)
// {
// if (dp[i][i + k - 1] < dp[i][j] + dp[j + 1][i + k - 1])
// {
// s[i][i + k - 1] = j;
// dp[i][i + k - 1] = dp[i][j] + dp[j + 1][i + k - 1];
// }
// }
// dp[i][i + k - 1] += w[i][i + k - 1];
// }
// }
//}
void getOutput()
{
long long result = maxvalue;
//for(int i=0; i<n; ++i)
//{
// if (result > dp[i][n + i - 1]) result = dp[i][n + i - 1];
//}
printf("%lld\n", dp[m-1][n-1]);
system("pause");
}
int main()
{
getInput();
process();
getOutput();
}