【codeforces】Codeforces Round#612(Div。2)C.ガーランド——DP

トピックリンク
Greedyは長い間シミュレーションされ、ついに諦めました

題名

1-n 1-nの文字列を与える1一部が不明な nのシーケンス(0として表されます)。完了シーケンスにより、
隣接する値の数がパリティーで反対になり、隣接する値の数が最小になり、反対になります。2つの隣接する値の1つは奇数で、もう1つはさえ

分析

最初は貪欲が使用され、結果は12番目の例で止まり、次にdpに変更し
て次のようにdp配列定義しました。

int dp[120][60][2];
// dp[i][j][0/1] 表示第i+1个位置放了偶/奇数,且到第i+1处总共放了j个奇数,有多少个奇偶性相反

状態遷移方程式を取得する

dp[i][j][1] = min(dp[i - 1][j - 1][0] + 1, dp[i - 1][j - 1][1]);
dp[i][j][0] = min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]);

もちろん、位置自体にすでに値があるかどうかによって異なりますが、0の場合は両方が必要です。すでに値がある場合は、元の値に従ってdpを実行します。

ACコード

#include <bits/stdc++.h>

using namespace std;

void solve() {
    
    
    int n;
    int dp[120][60][2], value[120];
    cin >> n;
    for (int i = 0; i < n; ++i) {
    
    
        cin >> value[i];
    }
    memset(dp, 0x3f, sizeof(dp));
    if (value[0] == 0)
        dp[0][1][1] = dp[0][0][0] = 0;
    else
        dp[0][value[0] & 1][value[0] & 1] = 0;
    for (int i = 1; i < n; ++i) {
    
    
        for (int j = 0; j <= min(i + 1, (n + 1) / 2); ++j) {
    
    
            if ((value[i] & 1 || value[i] == 0) && j > 0)
                dp[i][j][1] = min(dp[i - 1][j - 1][0] + 1, dp[i - 1][j - 1][1]);
            if (!(value[i] & 1))
                dp[i][j][0] = min(dp[i - 1][j][1] + 1, dp[i - 1][j][0]);
        }
    }
    cout << min(dp[n - 1][(n + 1) / 2][1], dp[n - 1][(n + 1) / 2][0]) << endl;
}

int main() {
    
    
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifdef ACM_LOCAL
    freopen("in.txt", "r", stdin);
    freopen("out.txt", "w", stdout);
    long long test_index_for_debug = 1;
    char acm_local_for_debug;
    while (cin >> acm_local_for_debug) {
    
    
        cin.putback(acm_local_for_debug);
        if (test_index_for_debug > 20) {
    
    
            throw runtime_error("Check the stdin!!!");
        }
        auto start_clock_for_debug = clock();
        solve();
        auto end_clock_for_debug = clock();
        cout << "Test " << test_index_for_debug << " successful" << endl;
        cerr << "Test " << test_index_for_debug++ << " Run Time: "
             << double(end_clock_for_debug - start_clock_for_debug) / CLOCKS_PER_SEC << "s" << endl;
        cout << "--------------------------------------------------" << endl;
    }
#else
    solve();
#endif
    return 0;
}

おすすめ

転載: blog.csdn.net/m0_43448982/article/details/103854850