1296: [SCOI2009]粉刷匠

Time Limit: 10 Sec Memory Limit: 162 MB

Submit: 2544 Solved: 1466

[Submit][Status][Discuss]

Description

windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。 windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。 如果windy只能粉刷 T 次,他最多能正确粉刷多少格子? 一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

Input

输入文件paint.in第一行包含三个整数,N M T。 接下来有N行,每行一个长度为M的字符串,’0’表示红色,’1’表示蓝色。

Output

输出文件paint.out包含一个整数,最多能正确粉刷的格子数。

Sample Input

3 6 3

111111

000000

001100

Sample Output

16

HINT

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

题解

本蒟蒻不会什么太高深的做法,就猛写了一发毒瘤dp,莫名其妙过了

dp[i][j][k][0/1/2]表示第i行第j列一共粉刷了k次,0/1/2分别表示当前格子没有涂色/涂了错的颜色
/涂了对的颜色, 然后我们考虑逐格转移: 当j=1也就是出于每行的第一个位置时,我们要考虑上一行的最后一个位置, 即 dp[i][j][k][0]=max(dp[i-1][m][k][1],max(dp[i-1][m][k][2],dp[i-1][m][k][0])); dp[i][j][k][1]=max(dp[i-1][m][k-1][2],max(dp[i-1][m][k-1][1],dp[i-1][m][k-1][0])); dp[i][j][k][2]=max(dp[i-1][m][k-1][2],max(dp[i-1][m][k-1][1],dp[i-1][m][k-1][0]))+1;
其余位置要考虑这个格子颜色是否和前一个格子的颜色相等,如果相等,就有 dp[i][j][k][2]=dp[i][j-1][k][2]+1;
可以直接接上 dp[i][j][k][1]=max(dp[i][j-1][k][1],dp[i][j-1][k-1][0]);
前面涂错或不涂 dp[i][j][k][0]=max(dp[i][j-1][k][0],dp[i][j-1][k][1]);
前面涂错或不涂
如果不相等, dp[i][j][k][2]=max(dp[i][j-1][k-1][2],max(dp[i][j-1][k][1],dp[i][j-1][k-1][0]))+1;
前面可能有三种情况 dp[i][j][k][1]=max(dp[i][j-1][k][2],dp[i][j-1][k-1][0]);
涂对或不涂 dp[i][j][k][0]=max(dp[i][j-1][k][0],dp[i][j-1][k][2]);
涂对或不涂

可以用滚动数组压掉第一维,这样空间复杂度是O(nT),时间复杂度是O(nmT),还是可以过的

代码

#include<bits/stdc++.h>

using namespace std;
const int MAXN = 55; int n,m,t,dp[3][MAXN][2505][3];
bool col[MAXN][MAXN]; int main(){
scanf("%d%d%d",&n,&m,&t);
for(register int i=1;i<=n;i++){
char c[MAXN];
scanf("%s",c+1);
for(register int j=1;j<=m;j++)
col[i][j]=c[j]-'0';
}
for(register int i=1;i<=n;i++)
for(register int j=1;j<=m;j++)
for(register int k=1;k<=t;k++){
if(j==1){
dp[i&1][j][k][0]=max(dp[(i-1)&1][m][k][1],dp[(i-1)&1][m][k][0]);
dp[i&1][j][k][0]=max(dp[i&1][j][k][0],dp[(i-1)&1][m][k][2]);
dp[i&1][j][k][1]=max(dp[(i-1)&1][m][k-1][1],dp[(i-1)&1][m][k-1][0]);
dp[i&1][j][k][1]=max(dp[i&1][j][k][1],dp[(i-1)&1][m][k-1][2]);
dp[i&1][j][k][2]=max(dp[(i-1)&1][m][k-1][1],dp[(i-1)&1][m][k-1][0])+1;
dp[i&1][j][k][2]=max(dp[i&1][j][k][2],dp[(i-1)&1][m][k-1][2]+1);
}
else{
if(col[i][j]==col[i][j-1]){
dp[i&1][j][k][2]=dp[i&1][j-1][k][2]+1;
dp[i&1][j][k][1]=max(dp[i&1][j-1][k][1],dp[i&1][j-1][k-1][0]);
dp[i&1][j][k][0]=max(dp[i&1][j-1][k][0],dp[i&1][j-1][k][1]);
}
else{
dp[i&1][j][k][2]=max(dp[i&1][j-1][k][1],dp[i&1][j-1][k-1][0])+1;
dp[i&1][j][k][2]=max(dp[i&1][j-1][k-1][2]+1,dp[i&1][j][k][2]);
dp[i&1][j][k][1]=max(dp[i&1][j-1][k][2],dp[i&1][j-1][k-1][0]);
dp[i&1][j][k][0]=max(dp[i&1][j-1][k][0],dp[i&1][j-1][k][2]);
}
}
// cout<<dp[i][j][k][0]<<" "<<dp[i][j][k][1]<<" ";
// cout<<dp[i][j][k][2]<<endl;
}
printf("%d",max(max(dp[n&1][m][t][0],dp[n&1][m][t][1]),dp[n&1][m][t][2]));
return 0;
}

BZOJ 1296(SCOI 2009) 粉刷匠的更多相关文章

  1. 【BZOJ 1296】 [SCOI2009]粉刷匠

    [链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] f[i][j][k]表示第i行前j列刷了k次,最大满意度 f[][j][k]=max{f[i][l][k],f[i][l][k-1] ...

  2. [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】

    题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...

  3. [BZOJ 1297][SCOI 2009]迷路(矩阵快速幂)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1297 分析:如果每条边的边权都是1,那么就相当于对邻接矩阵自乘T次(因为写一下递推式子 ...

  4. BZOJ 1024 SCOI 2009 生日快乐 深搜

    题目大意:有一块蛋糕,长为X,宽为Y.如今有n个人来分这块蛋糕,还要保证每一个人分的蛋糕的面积相等.求一种分法,使得全部的蛋糕的长边与短边的比值的最大值最小. 思路:刚拿到这个题并没有什么思路.可是定 ...

  5. bzoj 1024 [ SCOI 2009 ] 生日快乐 —— 递归

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 因为每次把一块切成两块,所以可以枚举从哪里切开,然后递归求解: 一开始用了不太对的贪心 ...

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

    1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上 ...

  7. BZOJ 1296: [SCOI2009]粉刷匠( dp )

    dp[ i ][ j ] = max( dp[ i - 1 ][ k ] + w[ i ][ j - k ] )  ( 0 <= k <= j ) 表示前 i 行用了 j 次粉刷的机会能正 ...

  8. 2014.7.8模拟赛【笨笨当粉刷匠】|bzoj1296 [SCOI]粉刷匠

    笨笨太好玩了,农田荒芜了,彩奖用光了,笨笨只好到处找工作,笨笨找到了一份粉刷匠的工作.笨笨有n条木板需要被粉刷.每条木板被分成m个格子,每个格子要被刷成红色或蓝色.笨笨每次粉刷,只能选择一条木板上一段 ...

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

    1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1919  Solved: 1099[Submit][Statu ...

随机推荐

  1. Javascript原型对象中的toString

    <script> //tostring function Person(name,age,gender){ this.name=name; this.age=age; this.gende ...

  2. PushSharp 由于远程方已关闭传输流,身份验证失败。

    前段时间用到了PushSharp给APNS发推送,但是用的时候遇见很诡异的事情,每次第一次运行的时候能成功发送到 但是接下来就无限的提示“由于远程方已关闭传输流,身份验证失败. “ 然后我就各种找原因 ...

  3. 【命令】Maven命令

    当前项目的依赖树: mvn dependency:tree -U.-B.-e -U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默 ...

  4. 53 windows 系统下

    0 引言 本篇主要记录windows下编程以及系统安装与恢复等问题. 1 Visual Studio (1)debug "warning LNK4042: 对象被多次指定:已忽略多余的指定& ...

  5. NX二次开发-UFUN获取球的参数UF_MODL_ask_sphere_parms

    NX11+VS2013 #include <uf.h> #include <uf_modl.h> #include <uf_ui.h> UF_initialize( ...

  6. linux centos 安装配置rsync

    先安装rsync yum install rsync 创建文件,并配置权限 touch /etc/rsyncd.conf touch /etc/rsyncd.secrets /etc/rsyncd.s ...

  7. 其它课程中的python---4、Matplotlib最最最最简单使用

    其它课程中的python---4.Matplotlib最最最最简单使用 一.总结 一句话总结: 慢慢来吧,不着急,心态平和和沉稳:每次和世界交互,你就能感受到无比的自信 1.如何区别python2和p ...

  8. P1650 赛马

    P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...

  9. docker 环境搭建步骤

    配置CA: zhaoweipeng@bogon:~$ ls106 baseos.tar fabric-sdk fabric-sdk (1).tar fixture_106zhaoweipeng@bog ...

  10. Python 查看QQ状态

    import requests """ 该程序依赖于QQ的端口程序 返回数据:String,Y = 在线:N = 离线:E = QQ号码错误:A = 商业用户验证失败:V ...