粉刷匠 BZOJ - 1296

題目傳送門

思路:這個題先對每一塊木板進行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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章