P4158 [SCOI2009]粉刷匠(分组背包问题+前缀和优化)

news2024/9/20 18:41:36

@[TOC](P4158 [SCOI2009]粉刷匠(分组背包问题))

一、问题

[SCOI2009]粉刷匠

题目描述

windy有 N 条木板需要被粉刷。 每条木板被分为 M 个格子。 每个格子要被刷成红色或蓝色。

windy每次粉刷,只能选择一条木板上一段连续的格子,然后涂上一种颜色。 每个格子最多只能被粉刷一次。

如果windy只能粉刷 T 次,他最多能正确粉刷多少格子?

一个格子如果未被粉刷或者被粉刷错颜色,就算错误粉刷。

输入格式

第一行包含三个整数,N M T。

接下来有N行,每行一个长度为M的字符串,'0’表示红色,'1’表示蓝色。

输出格式

包含一个整数,最多能正确粉刷的格子数。

样例 #1

样例输入 #1

3 6 3
111111
000000
001100

样例输出 #1

16

提示

30%的数据,满足 1 <= N,M <= 10 ; 0 <= T <= 100 。

100%的数据,满足 1 <= N,M <= 50 ; 0 <= T <= 2500 。

二、分析

我们将粉刷的次数看作背包的容量,正确粉刷的个数看作价值。将每一条木板看作一个物品组。那么这道题就转化成了,我们将 t t t分到不同的物品组里,我们能够得到的最大价值。

那么现在这道题的难点就转化成了,对于一个木板,在不同粉刷次数的情况下,我们能够粉刷的最大的正确方格数?

我们就先来解决这个问题。

g [ i ] [ j ] [ k ] g[i][j][k] g[i][j][k]表示,对第 i i i条木板的前 j j j个格子至多进行 k k k次涂色,在该条件下,我们能够获得的最大价值。

如果我们第 k k k次不涂色的话,
g [ i ] [ j ] [ k ] = g [ i ] [ j ] [ k − 1 ] g[i][j][k]=g[i][j][k-1] g[i][j][k]=g[i][j][k1]

如果第 k k k次涂色的话,我们可以去枚举第 k k k次涂色的区间。该区间所涂的颜色取决于该区间内是蓝色多还是红色多,也就是说我们需要提前统计出所有区间内的红色块和蓝色块的个数。该操作可以通过前缀和算法高效地实现。

转移的过程,我们可以通过枚举第 k k k次涂色的区间的左端点。不妨将该区间内的1的个数记作 s u m 1 sum1 sum1,0的个数记作 s u m 0 sum0 sum0。则转移方程如下:
g [ i ] [ j ] [ k ] = m a x ( g [ i ] [ j ] [ k ] , g [ i ] [ q ] [ k − 1 ] + m a x ( s u m 1 , s u m 0 ) ) g[i][j][k]=max(g[i][j][k],g[i][q][k-1]+max(sum1,sum0)) g[i][j][k]=max(g[i][j][k],g[i][q][k1]+max(sum1,sum0))
在这里插入图片描述
当我们求出 g g g数组之后,后续过程只需要套一个分组背包的板子即可。
我们让 f [ i ] [ j ] f[i][j] f[i][j]表示在前 i i i个板子中涂 j j j次颜色,所能获得的最大正确格子数。
状态转移即:
f [ i ] [ j ] = m a x ( f [ i − 1 ] [ j − k ] + g [ i ] [ m ] [ k ] , f [ i ] [ j ] ) f[i][j]=max(f[i-1][j-k]+g[i][m][k],f[i][j]) f[i][j]=max(f[i1][jk]+g[i][m][k],f[i][j])
其中 k k k是分给第 i i i个板子的粉刷次数, m m m是该木板的格子数目。

三、代码

#include<bits/stdc++.h>
#define endl '\n'
#define INF 0x3f3f3f3f
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
int f[51][2550],sum_1[51][60], sum_0[51][60];
int g[51][51][2550];
int n,m,t;
char s[60][60];

void solve()
{
	cin >> n >> m >> t;

	for(int i = 1; i <= n; i ++)
	{
		scanf("%s", s[i] + 1);
		for(int j = 1; j <= m; j ++ )
			if(s[i][j] == '1')
			{
				sum_1[i][j] = sum_1[i][j - 1] + 1;
				sum_0[i][j] = sum_0[i][j - 1];
			}
			else
			{
				sum_0[i][j] = sum_0[i][j - 1] + 1;
				sum_1[i][j] = sum_1[i][j - 1];
			}
	}

	for(int i = 1; i <= n; i ++)
	{
		for(int j = 1; j <= m; j ++)
			for(int k = 1; k <= m; k ++)
			{
				g[i][j][k] = g[i][j][k - 1];
				for(int q = 0; q < j; q ++)
				{
					int sum1 = sum_1[i][j] - sum_1[i][q];
					int sum0 = sum_0[i][j] - sum_0[i][q];
					g[i][j][k] = max(g[i][q][k - 1] + max(sum1, sum0), g[i][j][k]);
				}
			}
	}


	for(int i = 1; i <= n; i ++ )
		for(int j = 1; j <= t; j ++ )
			for(int k=0;k<=min(j,m);k++)
			{
				f[i][j] = max(f[i][j], f[i - 1][j - k] + g[i][m][k]);
			}

	cout << f[n][t] << endl;
}

signed main()
{
	solve();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/432270.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring Cloud Gateway: 网关

文章目录 网关Hello world路由: Route谓词: Predicate过滤器: FilterGateway实现限流: RequestRateLimiter过滤器使用Gateway实现服务降级 自定义全局过滤器GateWay中执行流程 网关 API网关就是实现了前端项目和服务端项目之间的统一入口 Nginx实现的是用户和前端项目之间调用…

【Linux】环境变量相关笔记

文章目录 echo $PATHexport和环境变量相关的命令main(int argc,char* argv[],char *env[])三个参数介绍getenv()通过系统调用获取su与su - 的区别&#xff1a;exportsource 和 .优先级 echo $PATH 是用来查环境变量的 export 从下面的图片当中可以看到&#xff0c;的确是将文…

ubuntu 20.04设置开机自启动脚本

1 建立开机启动服务 在 路径下 /lib/systemd/system/rc-local.service 的 rc-local.service 的脚本&#xff0c;内容规定了 rc.local 的启动顺序和行为 这行代码规定了这个service在开机启动时所执行的命令是&#xff1a;/etc/rc.local start。即运行 /etc/rc.local 脚本。不过…

《面试1v1》HashMap

没有人比中国人更懂 HashMap 我是 javapub&#xff0c;一名 Markdown 程序员从&#x1f468;‍&#x1f4bb;&#xff0c;八股文种子选手。 面试官&#xff1a;HashMap 是Java程序员用得最频繁的集合之一,可以给我简单介绍一下它的内部实现机制吗? 候选人&#xff1a; Hash…

C++ -3- 类和对象 (中) | 拷贝构造函数 赋值运算符重载

文章目录 4.拷贝构造函数什么是拷贝构造函数&#xff1f;应用——示例&#xff1a;日期计算器什么情况下需要自己实现拷贝构造函数&#xff1f; 5.赋值运算符重载运算符重载&#xff08;重要&#xff09;赋值运算符重载 拷贝构造函数和赋值重载函数 4.拷贝构造函数 什么是拷贝…

Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCV实现Mono12和Mono16格式位深度的图像保存(C++)

Baumer工业相机堡盟工业相机如何联合BGAPI SDK和OpenCV实现Mono12和Mono16位深度的图像保存&#xff08;C&#xff09; Baumer工业相机Baumer工业相机保存位深度12/16位图像的技术背景代码案例分享1&#xff1a;引用合适的类文件2&#xff1a;BGAPI SDK在图像回调中联合OpenCV保…

Effective C++条款条款42:了解typename的双重意义(Understand the two meanings of typename)

Effective C条款条款42&#xff1a;了解typename的双重意义&#xff08;Understand the two meanings of typename&#xff09; 条款42&#xff1a;了解typename的双重意义1、从属名称和非从属名称2、typename在traits机制中的运用3、牢记 总结 《Effective C》是一本轻薄短小的…

1.17 从0开始学习Unity游戏开发--场景切换

前面的所有文章我们都在一个固定的游戏场景内进行开发&#xff0c;在最开始介绍场景这个概念的时候就已经提及&#xff0c;这个场景可以是一张地图&#xff0c;或者是一个对战房间等等&#xff0c;所以显然这个场景可以有多个&#xff0c;并且可以从一个场景切换到另外一个场景…

Collection接口

文章目录 1. Java集合框架概述2. Collection接口中15个方法的使用3. Iterator(迭代器)接口4. Connection子接口一&#xff1a;List4.1 List的实现类4.2 源码分析4.2.1 ArrayList源码分析4.2.2 LinkedList源码分析4.2.3 Vector源码分析 4.3 List接口中的常用方法 5. Collection子…

死锁---银行家算法例题

1、知识点 1.银行家算法使用的四个必要的数据结构是: 可用资源向量Available&#xff0c;最大需求矩阵Max&#xff0c;分配矩阵Allocation&#xff0c;需求矩阵Need。 2.银行家算法是不是破坏了产生死锁的必要条件来达到避免死锁的目的&#xff1f;若是&#xff0c;请简述破…

【数字 IC / FPGA】 有关建立/保持时间计算的思考

引言 最近准备一些数字IC的机试&#xff0c;刷到了一些有关静态时序分析的题目。有一些比较经典的题目&#xff0c;在这里整理分享一下。 有什么疑问可以在评论区交流~互相进步 双D触发器典型电路 假设时钟周期为Tcycle,Tsetup,Thold分别为触发器建立保持时间&#xff0c;为…

Mac OS挂载ext4硬盘

一、安装macFUSE Home - macFUSE 如下载macfuse-4.4.3dmg安装 安装过程可能会遇到“若要要启用系统扩展,您需要在恢复环境中修改安全性设置”的提示&#xff0c;如下图&#xff1a; 解决&#xff1a; 关机&#xff0c;直到键盘灯全灭了&#xff01; 再按住开机键&#xff0c…

机器视觉技术分享-彩色图像处理 含c++ ,python代码说明

彩色图像处理是指对彩色图像进行数字处理和分析的过程&#xff0c;其目的是提取图像的有用信息&#xff0c;改善图像质量&#xff0c;实现图像的增强、复原、分割、匹配、识别等功能。 针对彩色图像处理&#xff0c;可以采用以下一些常见的方法&#xff1a; 1. 颜色空间转换&…

简简单单认识一下Inscode

CSDN最新推出的Inscode服务是一个在线编程工具&#xff0c;旨在为开发者提供一个便捷的编写、运行和分享代码的环境&#xff0c;让开发者无需在本地搭建编程环境&#xff0c;即可快速编写和运行代码。 Inscode支持多种编程语言&#xff0c;包括Java、Python、C等&#xff0c;同…

C语言进阶之回调函数详解分析方法

一、函数指针 在讲回调函数之前&#xff0c;我们需要了解函数指针。 我们都知道&#xff0c;C语言的灵魂是指针&#xff0c;我们经常使用整型指针&#xff0c;字符串指针&#xff0c;结构体指针等。 int *p1; char *p2; STRUCT *p3; // STRUCT为我们定义的结构体 但是好像我…

PlumGPT【告别梯子,拥抱AI】

相信很多人苦于没有openai账号或者有着种种原因至今还没有使用过chatgpt&#xff0c;今天向大家推荐一个网站&#xff0c;在国内也可以任意方便使用&#xff0c;让你的办公效率最大化。 那就是PlumGPT&#xff1a;https://plumgpt.com/ PlumGPT&#xff08;国内版的chatgpt&a…

Mybatis分页实现

1. Rowbounds Rowbounds将所有符合条件的数据加载到内存&#xff0c;然后再实现逻辑切割。 Override public List<User> getAllUser() {RowBounds rowBounds new RowBounds(1, 2);return userMapper.getAllUser(rowBounds); }查询sql&#xff08;没有任何分页逻辑&…

【Redis】常用命令、各种数据结构及命令

目录 一、常见数据结构 二、常用命令 1、查询符合的所有key 2、删除key 3、判断key是否存在 4、给key设置过期时间 5、查看key的剩余过期时间 三、不同数据类型的操作命令 1、String 1.set 2.get 3.mset 4.mget 5.incr 6.incrby 7.incrbyfloat 8.setnx 9.se…

C++——内存分配与动态内存管理

文章目录&#x1f490;专栏导读&#x1f490;文章导读&#x1f337;C/C内存分布&#x1f33a;牛刀小试&#x1f33a;C语言动态内存管理&#x1f337;C动态内存管理&#x1f33a;对于内置类型&#x1f33a;对于自定义类型&#x1f337;operator new与operator delete函数&#x…

便携式明渠流量计有哪几种呢?

便携式明渠流量计有几种&#xff1f; 目前来说市面上是有两种&#xff0c;但最终的作用或者说是功能都是用来和明渠在线流量计做液位和流量比对的一种装置。 这两种有什么区别呢&#xff1f; 一种就是便携式明渠流量计磁致伸缩流量计&#xff0c;另一种就是便携式明渠超声波…