粉刷匠 BZOJ
阿新 • • 發佈:2019-01-10
思路:這個題先對每一塊木板進行DP,dp[i][j]代表前i塊木塊用j次粉刷的符合要求的最大值,然後在對每一個木板進行一個揹包DP就可以了。
PS:這個題目不需要用檔案輸入輸出
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>
#define MAXN 2600
#define MAXE 110
#define INF 2100000000
#define MOD 100003
#define LL long long
#define ULL unsigned long long
#define pi 3.14159
using namespace std;
int dp[MAXN][MAXN];
int sum[MAXE];
int f[MAXN][MAXN];
int main() {
std ::ios::sync_with_stdio(false);
string str;
int n, m, t;
cin >> n >> m >> t;
memset(f, 0, sizeof(f));
for (int i = 1; i <= n; ++i) {
cin >> str;
memset(sum, 0, sizeof(sum));
memset(dp, 0, sizeof(dp));
for (int j = 1; j <= str.length(); ++j) {
if (str[j - 1] == '1')
sum[j] = sum[j - 1] + 1;
else
sum[j] = sum[j - 1];
}
for (int k = 1; k <= min(m, t); ++k) {
for (int j = 1; j <= m; ++j) {
for (int l = 0; l < j; ++l) {
dp[j][k] = max(dp[j][k], dp[l][k - 1] + max(j - l - (sum[j] - sum[l]), sum[j] - sum[l]));
}
}
}
for (int k = 1; k <= t; ++k) {
for (int j = 1; j <= min(m, k); ++j) {
f[i][k] = max(f[i][k], f[i - 1][k - j] + dp[m][j]);
}
}
}
int max_sum = 0;
for (int i = 1; i <= t; ++i) {
max_sum = max(max_sum, f[n][i]);
}
cout << max_sum << endl;
return 0;
}