首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

BZOJ 1296 【SCOI2009】粉刷匠:兩層動態規劃優化木板塗色

     編輯:關於C++

題目大意

N 條木板,每條 M 格。每格目標顏色為紅(0)或藍(1)。每次操作:選一條木板上連續段塗單一顏色。每格最多塗一次。共 T 次操作機會。求最多正確塗色格數(未塗或顏色錯誤均視為錯誤)。

資料範圍:N,M ≤ 50, T ≤ 2500。

核心觀察:木板獨立 + 兩層 DP

第一層 DP:單木板塗色最優解

木板間無相互影響,可獨立計算。對單木板,定義 f[j][k]:前 j 格使用 k 次操作,最多正確塗色格數。

前綴和 sum[j]:前 j 格中目標為藍(1)的格數。區間 [l+1, j] 塗藍正確數 = sum[j]-sum[l];塗紅正確數 = (j-l) - (sum[j]-sum[l])。取較大者。

轉移:

f[j][k] = max_{0≤l
  • 枚舉上一段結束位置 l,新段為 [l+1, j]。
  • 初始 f[0][0]=0,其餘 -inf。
  • 複雜度 O(M^3),M≤50 可接受。

計算出每木板 board[i][k] = f[M][k]:第 i 木板用 k 次操作的最大正確數。

第二層 DP:跨木板操作分配

定義 g[i][j]:前 i 條木板共用 j 次操作的最大正確總數。

轉移:

g[i][j] = max_{0≤k≤min(j,M)} { g[i-1][j-k] + board[i][k] }
  • 枚舉第 i 木板分配 k 次操作。
  • 初始 g[0][0]=0。
  • 複雜度 O(N * T * M) ≈ 50 × 2500 × 50 = 6.25e6,可接受。

答案:max_{0≤j≤T} g[N][j]。

完整程式碼

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define F(i,j,n) for(int i=j;i<=n;i++)
int n, m, t, ans = 0;
int sum[55], f[55][55], g[55][2505];
char s[55];

inline int read() {
    int x = 0, f = 1; char ch = getchar();
    while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); }
    while (ch >= '0' && ch <= '9') { x = x*10 + ch - '0'; ch = getchar(); }
    return x * f;
}

int main() {
    n = read(); m = read(); t = read();
    F(i, 1, n) {
        scanf("%s", s+1);
        F(j, 1, m) sum[j] = sum[j-1] + (s[j] == '1');
        F(k, 1, m) F(j, 1, m) {
            f[j][k] = 0;
            F(l, 0, j-1) {
                int tmp = sum[j] - sum[l];
                f[j][k] = max(f[j][k], f[l][k-1] + max(tmp, j-l-tmp));
            }
        }
        F(j, 1, t) F(k, 1, min(j, m))
            g[i][j] = max(g[i][j], g[i-1][j-k] + f[m][k]);
    }
    F(i, 1, t) ans = max(ans, g[n][i]);
    printf("%d\n", ans);
    return 0;
}

關鍵優化點

  • 單木板 DP 利用前綴和 O(1) 計算區間正確數。
  • 第二層 DP 直接在循環中累加最大值,無需額外初始化 -inf(靜態陣列預設 0,題目保證正確數非負)。
  • 快速輸入 read() 加速。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved