luoguP4158 [SCOI2009]粉刷匠
luoguP4158 [SCOI2009]粉刷匠
Description
Solution
先一个DP处理一波每一行
然后再做一个背包
#include<bits/stdc++.h> using namespace std; inline int read() { int f = 1,x = 0; char ch; do { ch = getchar(); if(ch == '-') f = -1; }while(ch < '0'||ch > '9'); do { x = (x<<3) + (x<<1) + ch - '0'; ch = getchar(); }while(ch >= '0'&&ch <= '9'); return f*x; } int n,m,t; char a[50 + 10]; int sum[50 + 10][50 + 10]; int dp[50 + 10][50 + 10][2500 + 10]; int ans[50+ 10][2500 + 10]; int main() { n = read(),m = read(),t = read(); for(int i=1;i<=n;i++) { scanf("%s",a+1); for(int j=1;j<=m;j++) { sum[i][j] = sum[i][j-1] + a[j] - '0'; } } for(int i=1;i<=n;i++) { for(int j=1;j<=m;j++) { for(int k=1;k<=min(t,j);k++) { for(int h=j-1;h>=k-1;h--) { dp[i][j][k] = max(dp[i][j][k] ,dp[i][h][k-1] + max(sum[i][j] - sum[i][h],j - h-(sum[i][j] - sum[i][h]))); } } } } int ans_M = 0; for(int i=1;i<=n;i++) { for(int j=1;j<=t;j++) { for(int k=1;k<=min(j,m);k++) ans[i][j] = max(ans[i][j],ans[i-1][j-k] + dp[i][m][k]); if(i==n) ans_M = max(ans_M , ans[i][j]); } } cout << ans_M << endl; }