先放题面

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. last_query_cost

    The total cost of the last compiled query as computed by the query optimizer. This is useful for com ...

  2. Codeforces ----- Kefa and Dishes [状压dp]

    题目传送门:580D 题目大意:给你n道菜以及每道菜一个权值,k个条件,即第y道菜在第x道后马上吃有z的附加值,求从中取m道菜的最大权值 看到这道题,我们会想到去枚举,但是很显然这是会超时的,再一看数 ...

  3. POJ2236:Wireless Network(并查集)

    Wireless Network Time Limit: 10000MS   Memory Limit: 65536K Total Submissions: 39772   Accepted: 164 ...

  4. codeforces 110E Lucky Tree

    传送门:https://codeforces.com/contest/110/problem/E 题意:给你一颗树,节点与节点之间的边有一个边权,定义只由4和7组成的数字是幸运数字,现在要你求一共有多 ...

  5. js 读写文件

    读写文件: var f = fso.CreateTextFile("c:\\pexam\\"+name+".txt", true); f.write(arr); ...

  6. Restful 接口权限控制

    前言 有人说,每个人都是平等的: 也有人说,人生来就是不平等的: 在人类社会中,并没有绝对的公平, 一件事,并不是所有人都能去做: 一样物,并不是所有人都能够拥有. 每个人都有自己的角色,每种角色都有 ...

  7. 查找算法总结Java实现

    之前对查找算法做的一些简单总结与实现: 查找算法时间复杂度: 1.二分查找的实现(待补充) public class Test { //循环实现二分查找 public static int binar ...

  8. TDS开启log TDS开启SSL

    参考: http://www.ibm.com/developerworks/tivoli/library/t-tds-perf/ 1. 编辑ldif文件如下 dn: cn=Audit, cn=Log ...

  9. 1552: [Cerc2007]robotic sort

    这道题用splay写 先离散化数据保证按题目所述顺序来写 按原序作为键值建树 维护区间最小值去跑 每次将i的位置 和 n的位置x和y找出来后 将x旋转到root y旋转到x的有儿子 这时y的左子树就是 ...

  10. react native windows 搭建(完整版)

    声明:用windows 搭建的react native只能开发安卓应用 1.准备安装java jdk,以及Android SDK 传送门: java   JDK   Android SDK(自行寻找) ...