先放题面

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及小小的优化的更多相关文章

  1. BZOJ1296 [SCOI2009]粉刷匠 动态规划 分组背包

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ1296 题意概括 有 N 条木板需要被粉刷. 每条木板被分为 M 个格子. 每个格子要被刷成红色或蓝 ...

  2. [bzoj1296][SCOI2009]粉刷匠(泛化背包)

    http://www.lydsy.com:808/JudgeOnline/problem.php?id=1296 分析: 首先预处理出每一行的g[0..T]表示这一行刷0..T次,最多得到的正确格子数 ...

  3. [Bzoj1296][Scoi2009] 粉刷匠 [DP + 分组背包]

    1296: [SCOI2009]粉刷匠 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2184  Solved: 1259[Submit][Statu ...

  4. bzoj1296: [SCOI2009]粉刷匠(DP)

    1296: [SCOI2009]粉刷匠 题目:传送门 题解: DP新姿势:dp套dp 我们先单独处理每个串,然后再放到全局更新: f[i][k]表示当前串枚举到第i个位置,用了k次机会 F[i][j] ...

  5. 【Dp】Bzoj1296 [SCOI2009] 粉刷匠

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

  6. BZOJ1296: [SCOI2009]粉刷匠 DP

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

  7. 2018.09.02 bzoj1296: [SCOI2009]粉刷匠(dp套dp)

    传送门 dp好题. 先推出对于每一行花费k次能最多粉刷的格子数. 然后再推前i行花费k次能最多粉刷的格子数. 代码: #include<bits/stdc++.h> #define N 5 ...

  8. BZOJ1296 [SCOI2009]粉刷匠 【dp】

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

  9. bzoj1296 [SCOI2009]粉刷匠——背包

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1296 对于不同木板之间,最终统计答案时做一个分组背包即可: 而要进行分组背包,就需要知道每个 ...

随机推荐

  1. greendao的基本操作

    1.先配置项目的builder.gradle // Top-level build file where you can add configuration options common to all ...

  2. python监控服务器

    import paramikoimport threadingimport reimport timeimport stringfrom sendmail import send_maildef ss ...

  3. React 获取 url 参数 —— this.props.match

    在 react 组件的  componentDidMount 方法中打印一下 this.props,在浏览器控制台中查看输出如下: 其中页面的 url 信息全都包含在 match 字段中,以地址 lo ...

  4. [bzoj4515][Sdoi2016]游戏-树链剖分+李超线段树

    Brief Description Alice 和 Bob 在玩一个游戏. 游戏在一棵有 n 个点的树上进行.最初,每个点上都只有一个数字,那个数字是 123456789123456789. 有时,A ...

  5. bzoj 1251 裸splay

    裸的splay,只需要注意 max[-1]:=-maxlongint 就行了,否则在update的时候子节点的 max值会在max[-1]里选 /*************************** ...

  6. Codeforces 940F Machine Learning 带修改莫队

    题目链接 题意 给定一个长度为\(n\)的数组\(a\),\(q\)个操作,操作分两种: 对于区间\([l,r]\),询问\(Mex\{c_0,c_1,c_2,⋯,c_{10^9}\}\),其中\(c ...

  7. Python学习笔记 - day4 - 流程控制

    Python流程控制 Python中的流程控制主要包含两部分:条件判断和循环. Python的缩进和语法 为什么要在这里说缩进和语法,是因为将要学习的条件判断和分支将会涉及到多行代码,在java.c等 ...

  8. 转:Android 的一些比较好的开源代码项目

    转自:http://blog.csdn.net/zengyangtech/article/details/7019439 Android PDF 阅读器 http://sourceforge.net/ ...

  9. [Leetcode Week11]Kth Largest Element in an Array

    Kth Largest Element in an Array 题解 题目来源:https://leetcode.com/problems/kth-largest-element-in-an-arra ...

  10. Android源码的BUG

    在Android系统移植过程中,遇到很多源码上的BUG.但是我们看到市面上都是没有这些问题的.难道这些BUG在每个开发商都要经历一次解BUG的过程吗?Android释放的源码是否是最新的?暂时没有想法 ...