BZOJ 1296(SCOI 2009) 粉刷匠
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) 粉刷匠的更多相关文章
- 【BZOJ 1296】 [SCOI2009]粉刷匠
[链接] 我是链接,点我呀:) [题意] 在这里输入题意 [题解] f[i][j][k]表示第i行前j列刷了k次,最大满意度 f[][j][k]=max{f[i][l][k],f[i][l][k-1] ...
- [BZOJ 1026] [SCOI 2009] Windy数 【数位DP】
题目链接:BZOJ - 1026 题目分析 这道题是一道数位DP的基础题,对于完全不会数位DP的我来说也是难题.. 对于询问 [a,b] 的区间的答案,我们对询问进行差分,求 [0,b] - [0,a ...
- [BZOJ 1297][SCOI 2009]迷路(矩阵快速幂)
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1297 分析:如果每条边的边权都是1,那么就相当于对邻接矩阵自乘T次(因为写一下递推式子 ...
- BZOJ 1024 SCOI 2009 生日快乐 深搜
题目大意:有一块蛋糕,长为X,宽为Y.如今有n个人来分这块蛋糕,还要保证每一个人分的蛋糕的面积相等.求一种分法,使得全部的蛋糕的长边与短边的比值的最大值最小. 思路:刚拿到这个题并没有什么思路.可是定 ...
- bzoj 1024 [ SCOI 2009 ] 生日快乐 —— 递归
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1024 因为每次把一块切成两块,所以可以枚举从哪里切开,然后递归求解: 一开始用了不太对的贪心 ...
- BZOJ 1296: [SCOI2009]粉刷匠 分组DP
1296: [SCOI2009]粉刷匠 Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上 ...
- BZOJ 1296: [SCOI2009]粉刷匠( dp )
dp[ i ][ j ] = max( dp[ i - 1 ][ k ] + w[ i ][ j - k ] ) ( 0 <= k <= j ) 表示前 i 行用了 j 次粉刷的机会能正 ...
- 2014.7.8模拟赛【笨笨当粉刷匠】|bzoj1296 [SCOI]粉刷匠
笨笨太好玩了,农田荒芜了,彩奖用光了,笨笨只好到处找工作,笨笨找到了一份粉刷匠的工作.笨笨有n条木板需要被粉刷.每条木板被分成m个格子,每个格子要被刷成红色或蓝色.笨笨每次粉刷,只能选择一条木板上一段 ...
- 1296: [SCOI2009]粉刷匠[多重dp]
1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1919 Solved: 1099[Submit][Statu ...
随机推荐
- Javascript原型对象中的toString
<script> //tostring function Person(name,age,gender){ this.name=name; this.age=age; this.gende ...
- PushSharp 由于远程方已关闭传输流,身份验证失败。
前段时间用到了PushSharp给APNS发推送,但是用的时候遇见很诡异的事情,每次第一次运行的时候能成功发送到 但是接下来就无限的提示“由于远程方已关闭传输流,身份验证失败. “ 然后我就各种找原因 ...
- 【命令】Maven命令
当前项目的依赖树: mvn dependency:tree -U.-B.-e -U参数: 该参数能强制让Maven检查所有SNAPSHOT依赖更新,确保集成基于最新的状态,如果没有该参数,Maven默 ...
- 53 windows 系统下
0 引言 本篇主要记录windows下编程以及系统安装与恢复等问题. 1 Visual Studio (1)debug "warning LNK4042: 对象被多次指定:已忽略多余的指定& ...
- NX二次开发-UFUN获取球的参数UF_MODL_ask_sphere_parms
NX11+VS2013 #include <uf.h> #include <uf_modl.h> #include <uf_ui.h> UF_initialize( ...
- linux centos 安装配置rsync
先安装rsync yum install rsync 创建文件,并配置权限 touch /etc/rsyncd.conf touch /etc/rsyncd.secrets /etc/rsyncd.s ...
- 其它课程中的python---4、Matplotlib最最最最简单使用
其它课程中的python---4.Matplotlib最最最最简单使用 一.总结 一句话总结: 慢慢来吧,不着急,心态平和和沉稳:每次和世界交互,你就能感受到无比的自信 1.如何区别python2和p ...
- P1650 赛马
P1650 赛马 题目描述 我国历史上有个著名的故事: 那是在2300年以前.齐国的大将军田忌喜欢赛马.他经常和齐王赛马.他和齐王都有三匹马:常规马,上级马,超级马.一共赛三局,每局的胜者可以从负者这 ...
- docker 环境搭建步骤
配置CA: zhaoweipeng@bogon:~$ ls106 baseos.tar fabric-sdk fabric-sdk (1).tar fixture_106zhaoweipeng@bog ...
- Python 查看QQ状态
import requests """ 该程序依赖于QQ的端口程序 返回数据:String,Y = 在线:N = 离线:E = QQ号码错误:A = 商业用户验证失败:V ...