【Luogu1947】粉刷匠

先直接抛题解,等下在整理啦QwQ
我们先不管列,考虑每一行,很容易想到设f[i][j]表示**当前这一行**前i个数涂j次色所能正确涂色的最多格子数
再枚举一个k(j≤k≤i),考虑当前第k个格子到第i个格子的情况
我们要分情况讨论:
1. 第i个格子必须正确的刷,那么意味着k~i所刷的颜色必须是与i相同的颜色。我们用sum来表示k~i中与i颜色相同的格子个数,那么就可以递推:
$F[i][j]=max{F[k-1][j-1]+sum}(j≤k≤i)$
2. 第i个格子错误地刷,那么意味着k~i所刷的颜色必须是与i相反的颜色(总共只有两种颜色嘻嘻嘻),仍然用sum可以递推:
$F[i][j]=max{F[k-1][j-1]+i-k+1-sum}(j≤k≤i)$
以上两个取最大值即可。
但是,这道题到这里当然还没有做完——还有列没考虑呢!
其实很简单,我们记g[i][j]表示第i行涂j次色最多能正确涂的格子数,而题目说最多能涂t次色,是不是很容易想到背包问题!
至此就结束了,当然也有不少小的细节就见程序吧(解释上面应该差不多了,故代码就不注释了)

//F[i][j]
//1. F[k-1][j-1]+r
//2. F[k-1][j-1]+i-k+1+r
//r=k~i与i相同颜色的
//最后做背包
#include<cstdio>
#include<cstring>
#define MAX(x,y) (x>y?x:y)
#define MIN(x,y) (x<y?x:y)
const int N=55,T=2505;
int n,m,t;
int b[N][N],f[N][T],mx[N],g[N][T],dp[T];
int main()
{
    scanf("%d%d%d",&n,&m,&t);
    for(int i=1;i<=n;i++)
        for(int j=1;j<=m;j++)
        {
            scanf("%1d",&b[i][j]);
            if(j==1||b[i][j]!=b[i][j-1]) mx[i]++;
        }
    for(int l=1;l<=n;l++)
    {
        memset(f,0,sizeof(f));
        for(int i=1;i<=m;i++)
        {
            for(int j=1;j<=mx[l];j++)
            {
                int r=0;
                for(int k=i;k>=j;k--)
                {
                    if(b[l][k]==b[l][i]) r++;
                    f[i][j]=MAX(f[i][j],f[k-1][j-1]+r);
                    f[i][j]=MAX(f[i][j],f[k-1][j-1]+i-k+1-r);
                }
                g[l][j]=MAX(g[l][j],f[i][j]);
            }
        }
    }
    for(int i=1;i<=n;i++)
        for(int j=t;j>=1;j--)
            for(int k=1;k<=MIN(j,mx[i]);k++)
                dp[j]=MAX(dp[j],dp[j-k]+g[i][k]);
    printf("%d",dp[t]);
}
时间: 2024-08-07 19:16:55

【Luogu1947】粉刷匠的相关文章

1296: [SCOI2009]粉刷匠

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 916  Solved: 532[Submit][Status] Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果

BZOJ1296: [SCOI2009]粉刷匠

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 844  Solved: 486[Submit][Status] Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果

BZOJ 1296: [SCOI2009]粉刷匠

BZOJ 1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷. Input 输入文件paint.in第一行包含三个整数,N M T. 接下来有N行,每行一个长度为M的字符串,

1296: [SCOI2009]粉刷匠[多重dp]

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1919  Solved: 1099[Submit][Status][Discuss] Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多

BZOJ 1296: [SCOI2009]粉刷匠 分组DP

1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷. Input 输入文件paint.in第一行包含三个整数,N M T. 接下来有N行,每行一个长度为M的字符串,'0'表示

cojs 疯狂的粉刷匠 疯狂的斐波那契 题解报告

疯狂的斐波那契 学习了一些奇怪的东西之后出的题目 最外层要模p是显然的,然而内层并不能模p 那么模什么呢,显然是模斐波那契的循环节 那么我们可以一层层的求出每层的斐波那契循环节 之后在从内向外用矩阵乘法计算即可 至于如何求斐波那契的最小循环节,参见本博客的Fib求循环节那篇文章 当然这个题可以只求循环节,不求最小循环节,这样会好写的多 (然而我不会告诉你这样的话最后会爆掉long long) 疯狂的粉刷匠 我们设树上一共有k个联通点集 包含点i的联通点集有f(i)个 那么答案显然是sigma(f

bzoj1296【SCOI2009】粉刷匠

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1479  Solved: 837 [id=1296" style="color:blue; text-decoration:none">Submit][Status][Discuss] Description windy有 N 条木板须要被粉刷. 每条木板被分为 M 个格子. 每一个格子要被刷成红色或蓝色. windy每次粉刷.仅仅

[SCOI2009][BZOJ1296] 粉刷匠

1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1128  Solved: 660[Submit][Status][Discuss] Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少

【清北前紧急补课12】粉刷匠

我是一个粉刷匠粉刷本领强~~要想看真正的粉刷匠 请进入这小哥哥的blog 嘻嘻嘻 题目描述 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷一次. 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷. 输入输出格式 输入格式: 第一行包含三个整数,N M T. 接下来有N行,每行一个长度为M的