【12年特长生第二题】【DP】农场主

农 场 主 农场主


题目

小张是一个养马农场的农场主,他要把N只马分配到K个马房里,放置的规则是:第1 到 第Pi只马放入第一个马房,第Pi+1 到第Pk只放入第二个马房,…以此类推。此外对于每一个马房都有一个叫做“不高兴系数”,即白色马的数量*黑色马的数量。你的任务是合理地分配这N只马,使得它所有马房的“不高兴系数”和最小。

输入

从文件 f a r m e r . i n farmer.in farmer.in中读入数据,文件中第一行有 2 2 2 个整数: $N ( 1 <= N <= 500 ) $和 K ( 1 < = K < = N ) K ( 1 <= K <= N) K(1<=K<=N)
接下来的N行有N个数。第 I 行为第 I 只马的颜色: 1 是黑色, 0 是白色。

输出

将结果输出到文件 f a r m e r . o u t farmer.out farmer.out中,其结果为最小的“不高兴系数”的总和

输入样例

farmer.in
6 3
1
1
0
1
0
1

输出样例

farmer.out
2

解题思路

这题我们用DP来做
用f[i,j]表示用i个马房装j匹马的最小不高兴系数
首先要预处理第i匹马时有多少只白马,多少只黑马
接着DP,用少马房装少马去更新多马房装多马
所以动态转移方程为

a n s = m i n ( a n s , f [ i − 1 ] [ k ] + ( b l a c k [ j ] − b l a c k [ k ] ) ∗ ( w h i t e [ j ] − w h i t e [ k ] ) ) ans = min(ans, f[i - 1][k] + (black[j] - black[k]) * (white[j] - white[k])) ans=min(ans,f[i1][k]+(black[j]black[k])(white[j]white[k]))

程序如下

#include
#include
#include
#include

using namespace std;

int n, k, ans;

int a[10001], white[10001], black[10001], f[10001][1001];

int main()
{
	freopen("farmer.in","r",stdin);
	freopen("farmer.out","w",stdout);
	scanf("%d%d", &n, &k);
	for(int i = 1; i <= n; ++i)
	{
		scanf("%d", &a[i]);
		if(a[i] == 1)
		{
			white[i] = white[i - 1];
			black[i] = black[i - 1] + 1; //预处理
		}
		else
		{
			white[i] = white[i - 1] + 1;
			black[i] = black[i - 1]; 
		}	
	}
	for(int i = 1; i <= n; ++i)
		f[1][i] = white[i] * black[i];//统计
	for(int i = 2; i <= k; ++i)
		for(int j = i; j <= n - k + i; ++j)
		{
			ans = 2147483647;
			for (int k = i - 1; k <= j - 1; ++k)
				ans = min(ans, f[i - 1][k] + (black[j] - black[k]) * (white[j] - white[k]));//取最优的白马和黑马的分布
			f[i][j] = ans;
		}
	printf("%d",f[k][n]);
	return 0;
}

你可能感兴趣的:(DP,ssl)