【bzoj1296】【[SCOI2009]粉刷匠】多次背包dp及小小的优化
先放题面
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 。
先简单说说自己最开始的wa解法:对所有木板直接dp,只能从该木板的长度内或其他木板的末尾转移过来。dp方程定义为:dp[k][i][j]表示刷k次、在第i个木板的第j格结束。结果后来对拍后才发现这个有后效性,挂了。
正解:
对每一个木板先进行一次dp,求出第i个木板刷k次最多能刷对多少格。然后再拿每个木板作为一个组,进行分组背包(其实将木板作为一个泛化物品进行背包问题会理解的更形象?)
然后有一个小小的优化:
在dp时,我们需要枚举之前的状态来选择最优解。而这一重枚举可能会造成超时(没试过),所以希望把它优化掉。用不着单调队列优化,将需枚举的量和在一起,每次取一个最值保存下来
就像这样:
f[k][i][j]=max(cnt[0][i][j]+tmp0,cnt[1][i][j]+tmp1);
tmp0=max(tmp0,f[k-1][i][j]-cnt[0][i][j]);
tmp1=max(tmp1,f[k-1][i][j]-cnt[1][i][j]);
完整代码:
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char c[55][55];
int n,m,T,cnt[2][55][55],f[3000][55][55],dp[3000][55];
int main(){
scanf("%d%d%d",&n,&m,&T);
for(int k=1;k<=n;k++){
scanf("%s",c[k]+1);
for(int i=1;i<=m;i++){
cnt[0][k][i]=cnt[0][k][i-1]+(c[k][i]=='0');
cnt[1][k][i]=cnt[1][k][i-1]+(c[k][i]=='1');
}
}
int tmp0,tmp1;
for(int k=1;k<=m;k++){
for(int i=1;i<=n;i++){
tmp0=tmp1=0;
for(int j=1;j<=m;j++){
f[k][i][j]=max(cnt[0][i][j]+tmp0,cnt[1][i][j]+tmp1);
tmp0=max(tmp0,f[k-1][i][j]-cnt[0][i][j]);
tmp1=max(tmp1,f[k-1][i][j]-cnt[1][i][j]);
}
}
}
for(int k=1;k<=T;k++){
for(int i=1;i<=n;i++){
dp[k][i]=max(dp[k][i],dp[k][i-1]);
for(int j=1;j<=min(k,m);j++)
dp[k][i]=max(dp[k][i],dp[k-j][i-1]+f[j][i][m]);
}
}
printf("%d\n",dp[T][n]);
return 0;
}
【bzoj1296】【[SCOI2009]粉刷匠】多次背包dp及小小的优化的更多相关文章
- BZOJ1296 [SCOI2009]粉刷匠 动态规划 分组背包
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1296 题意概括 有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝 ...
- [bzoj1296][SCOI2009]粉刷匠(泛化背包)
http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...
- [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] ...
- 【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每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色. 每个格子最多只能被粉刷 ...
- bzoj1296 [SCOI2009]粉刷匠——背包
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1296 对于不同木板之间,最终统计答案时做一个分组背包即可: 而要进行分组背包,就需要知道每个 ...
随机推荐
- 几种不同的json格式解析
转连接: http://blog.csdn.net/whx405831799/article/details/42171191 内容很好 给服务端发送请求后,服务端会返回一连串的数据,这些数据在大部分 ...
- 定时导出用户数据(expdp,impdp)
一 定时导出数据: #!/bin/bash############################################################################### ...
- JS表单验证优化
var validate = (function(){ var messages = { isEmail : '输入正确格式邮箱', isPhoneNum : '输入正确手机号' }; var val ...
- HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.entity.PojoEntityTup
Caused by: org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.t ...
- 排序(bzoj 4552)
Description 在2016年,佳媛姐姐喜欢上了数字序列.因而他经常研究关于序列的一些奇奇怪怪的问题,现在他在研究一个难题 ,需要你来帮助他.这个难题是这样子的:给出一个1到n的全排列,现在对这 ...
- 2017年上海金马五校程序设计竞赛:Problem I : Frog's Jumping (找规律)
Description There are n lotus leaves floating like a ring on the lake, which are numbered 0, 1, ..., ...
- 关于dlib人脸对比,人脸识别
人脸检测 人脸特征点提取 人脸对比,等于两张人脸对比,识别 封装的所有识别函数,直接看下面调用就好了. # coding:utf-8 ''' 本本次封装,我主要是做两张人脸对比. 就只人脸识别部分,简 ...
- poj 2312 Battle City(优先队列+bfs)
题目链接:http://poj.org/problem?id=2312 题目大意:给出一个n*m的矩阵,其中Y是起点,T是终点,B和E可以走,S和R不可以走,要注意的是走B需要2分钟,走E需要一分钟. ...
- 【mysql优化1】表的优化与列类型选择
数据类型及字节数参考http://www.cnblogs.com/qlqwjy/p/8590639.html -------------------------表的优化:--------------- ...
- linux基础-临时和永久修改ip地址以及通配符相关
一.临时配置网络(ip,网关,dns) 修改临时ip地址: 1.ifconfig查看当前的网卡和ip地址 2.临时修改IP地址:ifconfig ens32 192.168.16.200/24,ifc ...