题意简述

一个 n × m n\times m n×m的矩阵,每个位置珂能是粉色(0表示)或者是蓝色(1表示),然后你珂以对同一行里连续一段长度的区间染上一种颜色(覆盖型),你能染 t t t次,每次不限长度。求你染到的正确的颜色的个数最多是多少。

思路框架

f [ i ] [ j ] f[i][j] f[i][j]表示前 i i i行染 j j j次最大染色个数。 g [ i ] [ j ] [ k ] g[i][j][k] g[i][j][k]表示第 i i i行染 j j j次只考虑前 k k k个格子最大方案。

具体思路

D P DP DP题分两步,设状态,求转移。

多数题目是状态不好设的。像这个题就是,我想了好久没想出来状态怎么设,看一下题解知道状态怎么设之后就是秒切。那么,我们这个题也是分两块来讲。

Part 1. 状态

首先 f f f是很好想的。答案就是 f [ n ] [ i ] ( i ∈ [ 1 , t ] ) f[n][i] (i\in [1,t]) f[n][i](i∈[1,t])中的最大值。

然后我们来求 f [ i ] [ j ] f[i][j] f[i][j]的转移。求着求着发现,我们先要枚举一个 k k k, k k k小于 j j j。转移的一部分就是 f [ n − 1 ] [ j − k ] f[n-1][j-k] f[n−1][j−k],就是上一行染 j − k j-k j−k次。还有 k k k次留给这一行。所以我们要加上一个数,这个数就是:第 i i i行中染 k k k次正确染色的最大值。

然后我们来求这个子问题。

Part 1.1 子问题的状态

设 g [ i ] [ j ] g[i][j] g[i][j]表示第 i i i行染 j j j次的答案。考虑转移。。。转你妈,缺状态。观察数据也能轻易发现,应该是 O ( n m t ) O(nmt) O(nmt)的算法,然后 O ( n t ) O(nt) O(nt)过是什么鬼,肯定还缺一维。

缺什么状态呢。我们发现,还和染到了那里有关。不妨再加上一个 k k k,表示我们考虑到第 k k k个位置。

Part 1.2 子问题的转移

然后就来推转移了。像这种有“考虑到第xxx个位置”为一个状态的 D P DP DP,通常我们用枚举断点作转移。枚举断点 q q q(我真的没名字了, i , j , k i,j,k i,j,k都用过了,就叫 q q q了,随便一点)。由定义, q q q小于 k k k。还有一个注意点, q q q是能取 0 0 0的。其原因是,我习惯枚举的是 q q q把区间分成 [ 0 , q ] [0,q] [0,q]和 [ q + 1 , k ] [q+1,k] [q+1,k]。显然, q q q取 0 0 0时也有意义。

然后我们要看 [ q + 1 , k ] [q+1,k] [q+1,k]中是蓝色多还是粉色多,哪个多我们就染那种颜色。这样显然是对的。然后我们只要维护一个前缀和出来,维护每一行内蓝色的前缀和,记为 s u m sum sum。看是 s u m [ i ] [ k ] − s u m [ i ] [ q ] sum[i][k]-sum[i][q] sum[i][k]−sum[i][q]大,还是 ( k − q ) − ( s u m [ i ] [ k ] − s u m [ i ] [ q ] ) (k-q)-(sum[i][k]-sum[i][q]) (k−q)−(sum[i][k]−sum[i][q])大。设这两个的最大值为 S S S。

那么 g [ i ] [ j ] [ k ] = m a x ( g [ i ] [ j − 1 ] [ q ] + S ) g[i][j][k]=max(g[i][j-1][q]+S) g[i][j][k]=max(g[i][j−1][q]+S)。

Part 1.3 时间复杂度?

看起来状态数是 O ( n m t ) O(nmt) O(nmt),转移数是 O ( m ) O(m) O(m),复杂度 O ( n m 2 t ) O(nm^2t) O(nm2t)。但是, g g g的第二维,即染了 j j j次那一维中,显然 j j j不会超过 m m m。因为这一行最多就 m m m个数,染 m m m次啥事都解决了。所以复杂度应该是 O ( n m 3 ) O(nm^3) O(nm3),即 O ( 5 0 4 ) O(50^4) O(504)。稳过。

子问题完毕

Part 2. 转移

好了,回到主线。有了 g g g之后,就珂以得到 f f f的转移:

$f[i][j]=max(f[i-1][j-k]+g[i][k][m]) $(哎哟这个式子不要太显然,我真的不想解释了)

( P a r t 2 Part2 Part2比 P a r t 1 Part1 Part1短很多,说明这个题重点在设状态,是个毒瘤题)

代码 (精髓)

#include <bits/stdc++.h>
using namespace std;
namespace Flandre_Scarlet
{#define N 61#define T 2602#define F(i,l,r) for(int i=l;i<=r;++i)#define D(i,r,l) for(int i=r;i>=l;--i)#define Fs(i,l,r,c) for(int i=l;i<=r;c)#define Ds(i,r,l,c) for(int i=r;i>=l;c)#define Tra(i,u) for(int i=G.Start(u),__v=G.To(i);~i;i=G.Next(i),__v=G.To(i))#define MEM(x,a) memset(x,a,sizeof(x))#define FK(x) MEM(x,0)int n,m,t;int sum[N][N];char mp[N][N];void R1(int &x){x=0;char c=getchar();int f=1;while(c<'0' or c>'9') f=(c=='-')?-1:1,c=getchar();while(c>='0' and c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();x=(f==1)?x:-x;}void Input(){R1(n),R1(m),R1(t);F(i,1,n){scanf("%s",mp[i]+1);sum[i][0]=0;F(j,1,m) {if (mp[i][j]=='1') sum[i][j]=sum[i][j-1]+1; else sum[i][j]=sum[i][j-1];} }}int f[N][T],g[N][T][N];void Soviet(){F(i,1,n) F(j,1,t) F(k,1,m) F(q,0,k-1){int ss=sum[i][k]-sum[i][q];int S=max(ss,(k-q)-ss);g[i][j][k]=max(g[i][j][k],g[i][j-1][q]+S);}F(i,1,n) F(j,1,t) F(k,0,min(j,m)) f[i][j]=max(f[i][j],f[i-1][j-k]+g[i][k][m]);printf("%d\n",*max_element(f[n]+1,f[n]+t+1));}#define Flan voidFlan IsMyWife(){Input();Soviet();}
}
int main()
{Flandre_Scarlet::IsMyWife();getchar();getchar();return 0;
}

bzoj 1296 洛谷4158 [SCOI2009]粉刷匠 题解相关推荐

  1. [洛谷P4158][SCOI2009]粉刷匠(动态规划)

    [洛谷P4158][SCOI2009]粉刷匠(动态规划) 题目描述 输入描述 输出描述 示例 输入 输出 题目思路 代码 欢迎关注微信公众号:Java后台开发 题目描述 windy有 N 条木板需要被 ...

  2. 【题解】洛谷P4158 [SCOI2009] 粉刷匠(DP)

    次元传送门:洛谷P4158 思路 f[i][j][k][0/1]表示在坐标为(i,j)的格子 已经涂了k次 (0是此格子涂错 1是此格子涂对)涂对的格子数 显然的是 每次换行都要增加一次次数 那么当j ...

  3. [洛谷]P4158 [SCOI2009]粉刷匠 (#线性dp+背包dp)

    题目描述 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被 ...

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

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

  5. bzoj 1296: [SCOI2009]粉刷匠(DP+DP)

    1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2339  Solved: 1348 [Submit][Sta ...

  6. 【题解】P4158 [SCOI2009]粉刷匠(DP,背包)

    [题解]P4158 [SCOI2009]粉刷匠 是一道资源规划 DP 的好题,但是我想了很久还去看了题解./kk我真菜. 题目链接 P4158 [SCOI2009]粉刷匠 - 洛谷 题意概述 发现自己 ...

  7. BZOJ1296:[SCOI2009]粉刷匠

    1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2038  Solved: 1182 [Submit][Sta ...

  8. [SCOI2009]粉刷匠 DP)

    [SCOI2009]粉刷匠 题目描述: windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上 ...

  9. [SCOI2009]粉刷匠 牛客DP入门

    0x00 题目来源 [SCOI2009]粉刷匠 0x10 Tag 线性DP.区间DP 0x20 题目描述 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色'0' ...

最新文章

  1. 拿来就能用!Dijkstra 算法实现快递路径优化
  2. 从SAE又回到BAE,感觉好轻松
  3. FPGA逻辑设计回顾(9)DDR的前世今生以及演变过程中的技术差异
  4. Linux操作系统下以不同颜色命名的文件类型
  5. 使用uniapp开发婚庆应用的时候开发公共组件请求网络数据的方式
  6. pycharm怎么查看代码结构,看函数定义、变量定义、类定义索引、目录?(左方structure)
  7. boost::endian模块实现conversion的测试程序
  8. SpringBoot 上传限制
  9. android如何不用系统签名,更新Android系统应用程序,带/不带平台签名
  10. 外贸电商选择美国服务器的优势分析
  11. 宏与内联(inline)的区别(转载)
  12. 教你在CorelDRAW中导入位图
  13. 穿山甲插屏广告居中_穿山甲跻身广告联盟头部阵营 如何实现增量创新?
  14. bzoj 1312: Hard Life 01分数规划+网络流
  15. SSM整合(spring mybatis)图书
  16. Python使用正则爬取51job
  17. 利用Css3样式属性Cursor来更换自定义个性化鼠标指针(光标)
  18. freeotp使用教程_软件使用教程
  19. 计算机二级办公软件高级应用操作题,谁有计算机二级办公软件高级应用技术word操作题目啊?...
  20. STL——vector与迭代器

热门文章

  1. linux文件夹权限777怎么设置,Linux:设置文件夹权限之777的含义
  2. 在linux终端xterm问题,Term,Xterm还是Uxterm?
  3. 乔布斯:关于Flash的几点看法
  4. abap开发注释快捷键_SAP ABAP 开发快捷键
  5. Vue change事件无效
  6. VUE3前端笔记 Mitt事务总线使用方法
  7. Java基于springboot+vue的企业人事员工工资考勤管系统 nodejs 前后端分离
  8. 【工业机器人编程培训】技术男中的扛把子!
  9. 龙珠直播php,揭秘 | 百万并发直播网站龙珠的性能秘籍
  10. 超级实用的javascript经典大全 js大全