[Luogu P4158] [SCOI2009]粉刷匠

洛谷传送门
题目描述

windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。

windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。

如果windy只能粉刷 T 次,他最多能正确粉刷多少格子?

一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

输入输出格式
输入格式:

第一行包含三个整数,N M T。

接下来有N行,每行一个长度为M的字符串,’0’表示红色,’1’表示蓝色。

输出格式:

包含一个整数,最多能正确粉刷的格子数。

输入输出样例
输入样例

3 6 3
111111
000000
001100

输出样例

16

说明

30%的数据,满足 1<=N 1 <= N , M<=10 M <= 10 0<=T<=100 0 <= T <= 100

100%的数据,满足 1<=N 1 <= N , M<=50 M <= 50 0<=T<=2500 0 <= T <= 2500

解题分析

一开始还以为是可以竖着涂和横着涂…那么这样显然不可做啊 最后发现原来是只能涂横排, 所以算出每一排涂 1T 1 → T 次能正确涂的最多的格子数, 再进行一次01背包即可。

代码如下:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <algorithm>
#define R register
#define gc getchar()
#define W while
#define IN inline
using namespace std;
char data[55][2505];
int p[55][55][2505], dp[55][2505];
int hang, lie, tim;
IN int findit(const int &row, const int &lef, const int &rig)
{//在剩下部分找, 当然是哪种颜色多涂哪种
   int rt = 0, oth;
    for (R int i = lef; i <= rig; ++i)
    {if(data[row][i] == '1') rt ++;}
    oth = rig - lef + 1 - rt;
    return max(oth, rt);
}
int main()
{
    scanf("%d%d%d", &hang, &lie, &tim);
    for (R int i = 1; i <= hang; ++i) scanf("%s", data[i] + 1);
    for (R int i = 1; i <= hang; ++i)
        for (R int j = 1; j <= lie; ++j)
            for (R int k = 1; k <= j && k <= tim; ++k)
                for (R int cur = 0; cur < j; ++cur)
                {
                    p[i][j][k] = max(p[i][j][k], p[i][cur][k - 1] + findit(i, cur + 1, j));
                }
    for (R int i = 1; i <= hang; ++i)
    {
        for (R int j = 1; j <= tim; ++j)
        {
            for (R int k = 0; k <= j; ++k)
            {
                dp[i][j] = max(dp[i][j], dp[i - 1][j - k] + p[i][lie][k]);
            }
        }
    }
    printf("%d", dp[hang][tim]);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值