这个转移方程不好想,尤其是一段值的解是中间,不明觉厉。dp[i][j] 用i个邮局,覆盖前j个村庄的最小值。
还有就是区间dp的平行四边形优化,这个题的转移方程并不是“区间DP”,所以枚举状态要逆着(很花时间),且用一个邮局覆盖都是从0断开了相当于没有断开。
类比于石子归并,矩阵链乘等标准区间DP,其所需状态之前就已经获得,不用倒推
#include <cstdio>
#include <cstring>
#include <iostream>
using namespace std;
const int NN=310;
const int INF=0x7fffffff;
int n,m;
int s[NN],dp[NN][NN],w[NN][NN],p[NN][NN];
void get_w()//求在i~j号村庄间建一个邮局的最小距离和
{
for (int i=1; i<n; i++)
for (int j=i+1; j<=n; j++)
{
if ((i+j)%2) w[i][j]=s[j]-s[(i+j)/2]*2+s[i-1];
else w[i][j]=s[j]-s[(i+j)/2]-s[(i+j)/2-1]+s[i-1];
}
}
void get_dp()
{
for (int i=1; i<=n; i++)
{
dp[1][i]=w[1][i];
p[1][i]=0;//注意这里
}
for (int c=2; c&l