1. 程式人生 > 實用技巧 >luoguP4158 [SCOI2009]粉刷匠

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; }