题目链接:http://codeforces.com/contest/321/problem/E
题意:给定n个元素,将其分成m块,每块的元素连续。n的元素两两之间有一个不和谐值。每块的代价为该块内元素两两不和谐值的和。求一种分法使得总不和谐值最小?
思路:f[i][j]表示前i个分成j块的最小代价,则f[i][j]=min(f[k][j-1]+Cost(k+1,i))。对于固定的j,随着i的增加,k单调不减。
int get()
{
char c=getchar();
while(!isdigit(c)) c=getchar();
return c-'0';
}
int a[N][N],n,m,f[N][808],p[N][N];
int Cost(int i,int j)
{
return a[j][j]-a[i-1][j]-a[j][i-1]+a[i-1][i-1];
}
void DP(int x,int L,int R,int optL,int optR)
{
int mid=(L+R)>>1;
f[mid][x]=INF;
int i,temp,pos;
for(i=optL;i<=min(mid,optR);i++)
{
temp=f[i-1][x-1]+Cost(i,mid);
if(temp<f[mid][x]) f[mid][x]=temp,pos=i;
}
if(L==R) return;
DP(x,L,mid,optL,pos);
DP(x,mid+1,R,pos,optR);
}
int main()
{
RD(n,m);
int i,j;
FOR1(i,n) FOR1(j,n)
{
a[i][j]=get();
a[i][j]+=a[i-1][j]+a[i][j-1]-a[i-1][j-1];
}
for(i=1;i<=n;i++) f[i][1]=Cost(1,i);
for(i=2;i<=m;i++) DP(i,1,n,1,n);
PR(f[n][m]>>1);
}