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. 基于LNMP架构部署wordpress

    [root@localhost ~]# yum -y install unzip[root@localhost ~]# unzip wordpress-5.2.3.zip[root@localhost ...

  2. JS自运行函数的写法和MVVM框架数据驱动的底层逻辑

    1.JS自运行函数的写法 ( function(){ console.log(111)} )( ) !function(){ console.log(111) }() ( function(){}() ...

  3. spark-sql中的分析函数的使用

    分析函数的应用场景: (1)用于分组后组内排序 (2)指定计算范围 (3)Top N (4)累加计算 (5)层次计算 分析函数的一般语法: 分析函数的语法结构一般是: 分析函数名(参数)  over  ...

  4. Java分页查询工具类

    public class PageList<T> { private int totalpage; //总页数 private int totalcount; //总记录数 private ...

  5. 帝国cms简介显示转义字符问题

    在模板中设置简介截取字数为0,前端显示用css控制即可 white-space: nowrap; overflow: hidden; text-overflow: ellipsis; 也可以 1,在后 ...

  6. JavaWeb学习篇之----EL表达式详解

    我们之前的几篇文章中都提到了一个EL表达式,那么这个EL表达式到底是什么东东呢?为什么用处那么大,下面我们就来看看EL表达式的相关内容 EL表达式简介: EL 全名为Expression Langua ...

  7. 线段树区间离散化——牛客多校E

    这个区间离散化把我调死了.. 总之用vector来离散化,然后叶子节点维护的是一段区间,记录下每个叶子结点的起点+长度 千万要注意下标不能弄错! #include<bits/stdc++.h&g ...

  8. bs4修改html文件和保存

    一.需求 将2个html文件保存到本地浏览器,例如: A页面(我的博客主页) B页面(爬虫四大金刚) 然后将A页面中的爬虫链接,链接的a标签中的href属性修改成本地B页面的地址,实现在本地浏览A页面 ...

  9. NX二次开发-UFUN创建图层类别UF_LAYER_create_category

    NX11+VS2013 #include <uf.h> #include <uf_layer.h> UF_initialize(); //创建图层类别 UF_LAYER_cat ...

  10. tomcat 优化到每秒并发1000

    tomcat并发线程数能达到多少? 答:tomcat 优化到每秒并发1000,需要以下优化: 一.优化tomcat中的配置(包括tomcat APR(Apache Portable Runtime)优 ...