Step1 Problem:
将n匹马按照顺序放进k个马厩,每个马厩的不愉快值 = 0马的数量 * 1马的数量,求最小的不愉快值
数据范围:
1 <= k <= n <= 500.
Step2 Involving algorithms:
DP
Step3 Ideas:
状态dp[k][n]:将n匹马按照顺序放进k个马厩的最小不愉快值。
状态转移方程:dp[k][n] = min(dp[k][n], dp[k-1][t-1] + sum(t, n); 其中t的范围[1,n]
需要预处理出sum(t, n)代表第t匹马 到 第n匹马的 在一个马厩的不愉快值。
Step4 Code:
#include<bits/stdc++.h>
using namespace std;
const int N = 505;
const int inf = 0x3f3f3f3f;
int dp[N][N], sum[N][N];
int zero[N][N], one[N][N];
int a[N];
void init()
{
memset(one, 0, sizeof(one));
memset(zero, 0, sizeof(zero));
memset(sum, 0, sizeof(sum));
}
int main()
{
int n, k;
while(cin >> n >> k)
{
for(int i = 1; i <= n; i++)
scanf("%d", &a[i]), dp[0][i] = inf;
for(int i = 1; i <= n; i++)//预处理出第i匹马到第j匹马在一个马厩的不愉快值
{
for(int j = i; j <= n; j++)
{
one[i][j] = one[i][j-1];
zero[i][j] = zero[i][j-1];
if(a[j]) one[i][j]++;
else zero[i][j]++;
sum[i][j] = one[i][j] * zero[i][j];
}
}
for(int i = 1; i <= k; i++)
{
for(int j = 1; j <= n; j++)
{
dp[i][j] = inf;
for(int t = 1; t <= j; t++)
{
dp[i][j] = min(dp[i][j], dp[i-1][t-1] + sum[t][j]);
}
// printf("%d\n", dp[i][j]);
}
}
printf("%d\n", dp[k][n]);
}
return 0;
}