1. 程式人生 > >粉刷匠 BZOJ

粉刷匠 BZOJ

題目傳送門

思路:這個題先對每一塊木板進行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; }