【洛谷4158/BZOJ1296】[SCOI2009]粉刷匠(动态规划)
题目:洛谷4158
分析:
这题一看就是动态规划。
可以看出,如果每个木条粉刷的次数是固定的,那么这些木条是互不干扰的,因此对于每个木条可以通过dp来求出把T次中的j次分配给这个木条时可以获得的最大正确数,然后再dp出如何分配这T个粉刷次数可以获得最优解(类似于背包)。
针对这个思路设计两个状态:
\(dp1[i][j]\)表示一个木条的前\(i\)个格子被粉刷j次时最大正确数
\(dp2[i][j]\)表示前i个木条粉刷\(j\)次时最大正确数
\(dp1\)能够这样设计的理由是:刷前\(a\)个格子显然不比只刷前\(a\)个格子中的一段差(因为后一种情况下没刷的格子一定是错误的)
于是能想cai到dp方程:
$$dp1[i][j]=max(dp1[i][j],dp1[k-1][j-1]+max(k-i中 0 的数量 , k-i中 1 的数量) )$$
(对这个木条的第$j$次粉刷是从$k$刷到$i$)
($k$~$j$中0、1的数量可以用前缀和来快速求出)
$$dp2[i][j]=max(dp2[i][j],dp2[i-1][j-k]+dp1[m][k])$$
(这个类似背包,不解释)
代码:
#include<cstdio>
#include<algorithm>
#include<string>
#include<cstring>
using namespace std;
int n,m,t,sum[60],dp1[60][2500],dp2[60][2500];
//sum[i]表示前i个格子中1的数量
//dp1[i][j]表示一个木条的前i个格子被粉刷j次时最大正确数
//dp2[i][j]表示前i个木条粉刷j次时最大正确数
char in[60];
int main(void)
{
scanf("%d%d%d",&n,&m,&t);
for(int i=1;i<=n;i++)
{
scanf("%s",in+1);
for(int i=1;i<=m;i++)
sum[i]=sum[i-1]+in[i]-'0';
memset(dp1,0,sizeof(dp1));
for(int i=1;i<=m;i++)
//一个木条被刷的次数不可能大于它的长度
for(int j=1;j<=m;j++)
for(int k=1;k<=j;k++)
//k表示第i次从第k个格子刷到第j个格子
dp1[j][i]=max(dp1[j][i],
dp1[k-1][i-1]+max(sum[j]-sum[k-1],j-k+1-(sum[j]-sum[k-1])));
//j-k+1-(sum[j]-sum[k-1]即从k到j中0的数量
for(int j=1;j<=t;j++)
{
for(int k=1;k<=min(j,m);k++)
dp2[i][j]=max(dp2[i][j],dp2[i-1][j-k]+dp1[m][k]);
}
}
printf("%d",dp2[n][t]);
return 0;
}
【洛谷4158/BZOJ1296】[SCOI2009]粉刷匠(动态规划)的更多相关文章
- 背包 DP【洛谷P4158】 [SCOI2009]粉刷匠
P4158 [SCOI2009]粉刷匠 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上 ...
- BZOJ1296 [SCOI2009]粉刷匠 动态规划 分组背包
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1296 题意概括 有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝 ...
- [Bzoj1296][Scoi2009] 粉刷匠 [DP + 分组背包]
1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2184 Solved: 1259[Submit][Statu ...
- bzoj1296: [SCOI2009]粉刷匠(DP)
1296: [SCOI2009]粉刷匠 题目:传送门 题解: DP新姿势:dp套dp 我们先单独处理每个串,然后再放到全局更新: f[i][k]表示当前串枚举到第i个位置,用了k次机会 F[i][j] ...
- bzoj 1296: [SCOI2009]粉刷匠 动态规划
Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...
- 【Dp】Bzoj1296 [SCOI2009] 粉刷匠
Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...
- BZOJ1296: [SCOI2009]粉刷匠 DP
Description windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个 ...
- 2018.09.02 bzoj1296: [SCOI2009]粉刷匠(dp套dp)
传送门 dp好题. 先推出对于每一行花费k次能最多粉刷的格子数. 然后再推前i行花费k次能最多粉刷的格子数. 代码: #include<bits/stdc++.h> #define N 5 ...
- BZOJ1296 [SCOI2009]粉刷匠 【dp】
题目 windy有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝色. windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷 ...
随机推荐
- CCF201609-1 最大波动 java (100分)
试题编号: 201609-1 试题名称: 最大波动 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 小明正在利用股票的波动程度来研究股票.小明拿到了一只股票每天收盘时的价格,他 ...
- Linux查看用户列表
cat /etc/passwd 可以查看所有用户的列表w 可以查看当前活跃的用户列表cat /etc/group 查看用户组 groups 查看当前登录用户的组内成员groups gliethttp ...
- np.tile(), np.repeat() 和 tf.tile()
以上三个函数,主要区别在于能够拓展维度上和重复方式: np.tile() 能够拓展维度,并且整体重复: a = np.array([0,1,2]) np.tile(a,(2,2)) # out # a ...
- NT9666X调试log
1.给GSensor_open();前加上打印函数DEBUG_P;打印如下信息: ######## FILE = e:/Project_code/Philips_PanGu/Philips_PanGu ...
- BZOJ 4976 [Lydsy1708月赛]宝石镶嵌
[题解] 我们设总共有m个二进制位出现过1,那么如果n-k≥m,显然所有的1都可以出现,那么答案就是把所有的数或起来. 如果n-k<m,那么因为k不超过100,ai不超过1e5,所以n不超过11 ...
- node-sass 安装失败
安装 npm install 时偶尔遇到报错:没有安装python或node-sass 安装失败的问题,百度之后发现是被墙了,但根据百度的方法换了淘宝镜像和用了vpn都安装失败, 原因可能是没有卸载之 ...
- 【GC概述以及查看堆内存使用】Java内存管理和GC学习
内存划分 1.JAVA内存主要划分为方法栈.方法区.堆. 2.方法栈上内存会自动释放: 3.方法区上主要加载了类的元信息.静态变量.常量.改区域又称为持久代(Perm Gen),默认是最小16M,最大 ...
- Spring——ClassPathXmlApplicationContext(配置文件路径解析 1)
ClassPathXmlApplicationContext 在我的 BeanFactory 容器文章中主要提及了 BeanFactory 容器初始化(Spring 配置文件加载(还没解析)) ...
- Build Tools主流是什么?为什么要使用它?
Build Tools 即构建工具是一个把源代码生成可执行应用程序的过程自动化的程序(例如Android app生成apk).构建包括编译.连接跟把代码打包成可用的或可执行的形式. 1.构建工具的作用 ...
- 将完整的Maven远程存储库下载到本地存储库(别试了,不太可取)
别试了,这种方式不太可取. 要解决可以有如下思路: 1.做成镜像站点,有如下命令: wget -m http://site.to.mirror.com #-m代表“镜子”. rsync repo1.m ...