ans[i][j]表示 第i个马厩放到第j只马时的最小不高兴值
blacksum[i]表示到第i只马时的黑马数
详解见代码注释
http://acm.timus.ru/problem.aspx?space=1&num=1167
#include<iostream>
#include<string>
#include<string.h>
#include<queue>
#include<math.h>
#include<algorithm>
#include<vector>
#include<stdio.h>
#define Max 0x7ffffff
using namespace std;
int ans[501][501];
int blacksum[501];
int dp(int i,int j)//第i个马厩放到第j只马时的最小不高兴值
{
if(ans[i][j]!=-1)//已查过 避免重复
return ans[i][j];
if(i==1)//只有一个马厩时
{
ans[i][j]=blacksum[j]*(j-blacksum[j]);//讲黑马数与白马数相乘
return ans[i][j];
}
if(i==j)//马厩与马数量一样
{
ans[i][j]=0;//这时只能放一只马 所以值为0
return ans[i][j];
}
if(i<j)//关键情况为马的数量多于马厩数量
{
ans[i][j]=Max;//先让其值等于最大
for(int l=1;l<=j-i+1;l++)//最多可放j-i+1只马 最少一只
{
int bn=blacksum[j]-blacksum[j-l];//放l只马时的黑马数量
ans[i][j]=min(ans[i][j],dp(i-1,j-l)+(bn*(l-bn)));//在l变化中取最小
}
return ans[i][j];
}
}
int main()
{
int n,k,i;
cin>>n>>k;
memset(blacksum,0,sizeof(blacksum));
for(i=1;i<=n;i++)
{
cin>>blacksum[i];
blacksum[i]+=blacksum[i-1];//到第i只马时的黑马数
}
memset(ans,-1,sizeof(ans));//初始化为-1
cout<<dp(k,n);
return 0;
}