[区间DP 中位数] BZOJ 2933 [Poi1999]地图 Map

来源:互联网 发布:安卓传输mac 编辑:程序博客网 时间:2024/05/29 07:12

区间DP没什么好想的  mn2也懒得优化了

中位数 这个递推好啊


P[i,j]有定义式为

P[i,j]=Sum{ Abs( S[k]-Mid(i,j) ) | i<=k<=j } (Mid(i,j)为S[i]..S[j]的中值)

但是如果我们直接这样求,时间复杂度高达O(N^3 + N^2*M),关键在于求P[i,j]时浪费了太多时间。其实我们可以递推求出P[i,j]。

递推式

P[i,j]=P[i+1,j] + Mid(i,j) - S[i]

边界

P[i,i]=0

来自BYVOID %%%


#include<cstdio>  #include<cstdlib>  #include<algorithm>#include<cstring>using namespace std;typedef long long ll;const int N=3005;const int M=15;int n,m;  ll a[N],f[N][M],w[N][N];int main(){  freopen("t.in","r",stdin);  freopen("t.out","w",stdout);  scanf("%d%d",&n,&m); for (int i=1;i<=n;i++) scanf("%lld",&a[i]);    sort(a+1,a+1+n);    for (int j=1;j<=n;j++)    for (int i=j-1;i;i--)       w[i][j]=w[i+1][j]+a[((i+1)+j)/2]-a[i];  memset(f,0x3f,sizeof(f));  f[0][0]=0;  for (int i=1;i<=n;i++)    for (int j=1;j<=m;j++)      for (int k=0;k<i;k++)  f[i][j]=min(f[i][j],f[k][j-1]+w[k+1][i]);  printf("%lld\n",f[n][m]);  return 0;  }  




0 0
原创粉丝点击