2019湘潭校赛 H(dp)

题目传送
dp是常规的;(m^2)的预处理:把位置存进vector然后(O(1))算出想要的;WA点:要注意特意设置一下val[i][v.size()]=0,即全天都放鸽子则花费时间为0.

#include <bits/stdc++.h>
using namespace std;

int T, n, m, d, ans;
int val[205][205], dp[205][205];
char s[205];

int main() {
    for (scanf("%d", &T); T; T--) {
        memset(val, 0x3f, sizeof val);
        memset(dp, 0x3f, sizeof dp);
        
        scanf("%d %d %d", &n, &m, &d);
        for (int i = 1; i <= n; i++) {
            scanf("%s", s + 1);
            vector<int> v;
            for (int j = 1; j <= m; j++) {
                if (s[j] == '1') {
                    v.push_back(j);
                }
            }
            val[i][v.size()] = 0;
            for (int j = 0; j < v.size(); j++) {
                for (int k = j; k < v.size(); k++) {
                    int l = v[j], r = v[k];
                    int angry = v.size() - (k - j + 1);
                    val[i][angry] = min(val[i][angry], r - l + 1);
                }
            }
        }
        for (int i = 0; i <= d; i++)
            dp[0][i] = 0;
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j <= d; j++) {
                for (int k = 0; k <= j; k++)
                    if (val[i][k] < 0x3f3f3f3f && dp[i - 1][j - k] < 0x3f3f3f3f)
                        dp[i][j] = min(dp[i][j], dp[i - 1][j - k] + val[i][k]);
            }
        }
        ans = 0x3f3f3f3f;
        for (int i = 0; i <= d; i++)
            ans = min(ans, dp[n][i]);
        printf("%d
", ans);
    }
}
原文地址:https://www.cnblogs.com/AlphaWA/p/10900519.html