洛谷p3392

P3392 涂条纹

题目描述

只要一个由 N \times M 个小方块组成的旗帜符合如下规则,就是合法的图案。

  • 从最上方若干行(至少一行)的格子全部是白色的;
  • 接下来若干行(至少一行)的格子全部是蓝色的;
  • 剩下的行(至少一行)全部是红色的;

现有一个棋盘状的布,分成了 NM 列的格子,每个格子是白色蓝色红色之一,小 a 希望把这个布改成合法图案,方法是在一些格子上涂颜料,盖住之前的颜色。

小 A 很懒,希望涂最少的格子,使这块布成为一个合法的图案。

输入格式

第一行是两个整数 N,M

接下来 N 行是一个矩阵,矩阵的每一个小方块是 W(白),B(蓝),R(红)中的一个。

输出格式

一个整数,表示至少需要涂多少块。

输入输出样例 #1

输入 #1

4 5
WRWRW
BWRWB
WRWRW
RWBWR

输出 #1

11

说明/提示

样例解释

目标状态是:

WWWWW
BBBBB
RRRRR
RRRRR

一共需要改 11 个格子。

数据范围

对于 100\% 的数据,3 \leq N,M \leq 50

思路:1,暴力枚举:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
int main(){
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m;
	if(!(cin>>n>>m)) return 0;
	vector<string>grid(n);
	for(int i=0;i<n;i++) cin>>grid[i];
	int min_cost=2500;
	//i表示白色区域的最后一行(注意下标凑从0开始,所以最大是n-3
	for(int i=0;i<=n-3;i++){
		//j表示蓝色区域的最后一行,因为必须再白色下面,所以从i+1开始
		//至少给红色留一行,所以j最大为n-2
		for(int j=i+1;j<=n-2;j++){
			int current_cost=0;
			//1,计算把0-i行全染成白色的代价
			for(int r=0;r<=i;r++){
				for(int c=0;c<m;c++){
					if(grid[r][c]!='W') current_cost++;
				}
			} 
			//计算从i+1到j行全染成b
			for(int k=i+1;k<=j;k++){
				for(int d=0;d<m;d++){
					if(grid[k][d]!='B') current_cost++;
				}
			} 
			//计算把从j+1行到第n-1行全染成红色的代价
			for(int p=j+1;p<=n-1;p++){
				for(int o=0;o<m;o++){
					if(grid[p][o]!='R') current_cost++;
				}
			}
			min_cost=min(min_cost,current_cost); 
		} 
	}
	cout<<min_cost<<endl; 
}

思路2:前缀和优化:

#include<bits/stdc++.h>
using namespace std;
#define endl '\n'
int main(){
	//为了让前缀和的计算更加自然,我们让数组的下标从1开始 
	ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
	int n,m;
	if(!(cin>>n>>m)) return 0;
	vector<string>grid(n+1);
	for(int i=1;i<=n;i++){
		string s;
		cin>>s;
		grid[i]=" "+s;//在字符串前面补一个空格。让真实的下标u而从1开始 
	}
	//prefW[i] 表示前i行全变成白色的代价,默认 初始化为0
	vector<int>preW(n+1,0);
	vector<int>preB(n+1,0);
	vector<int>preR(n+1,0);
	//1,预处理前缀和数组
	for(int i=1;i<=n;i++){
		int costW=0,costB=0,costR=0;
		//统计当前第i行变成W,R,B分别要改几个格子
		for(int j=1;j<=m;j++){
			if(grid[i][j]!='W') costW++;
			if (grid[i][j] != 'B') costB++;
			if (grid[i][j] != 'R') costR++;
		} 
		//把当前的第i行的结果累加到前缀和数组中 
		preW[i]=preW[i-1]+costW;
		preB[i]=preB[i-1] + costB;
		preR[i]=preR[i-1] + costR;
	} 
	int min_cost=n*m;//最大的代价不可能超过格子的总数
	//2.枚举分界线i和j,i从1开始到n-2
	for(int i=1;i<=n-2;i++){
		for(int j=i+1;j<=n-1;j++){
			int current_cost=preW[i]+preB[j]-preB[i]+preR[n]-preR[j];
			min_cost=min(min_cost,current_cost);
		}
	} 
	cout<<min_cost<<endl;
	return 0;
}

知识补充:https://gemini.google.com/app/e8f3b17bcc27a3f0?pli=1

喜欢的话就赞一下吧

全部评论

相关推荐

不愿透露姓名的神秘牛友
昨天 01:05
我的求职进度条
点赞 评论 收藏
分享
27届算法工程师,在联宝实习快结束了,马上要回学校。说来也挺好笑的,来之前我还担心过:会不会很无聊?会不会天天拧螺丝?到了之后发现,完全不是我想的那样。说几个让我意外的点吧:技术氛围比我想的浓。有iLab,有人机交互实验室,还有服务器创新中心。我参与的视觉检测项目后来真的用到了真实的生产场景里(虽然只是个试点),但这个经历写在简历里还是挺香的。每天的工作节奏挺舒服的,都是为了工作目标来做事,大家会一起沟通排期,也不会为了卷而卷,就属于忙而充实且有意义。有时候遇到卡点,吃饭时突然有了新想法,回去一试就通了——那种感觉真的很爽。导师不是挂名的,他会注重底层能力,遇到问题时帮助我们梳理问题思路,而不是直接提出解决方案。在他的帮助下,我现在解决问题的能力确实提升了好多,遇到一个很大的难题我也知道如何一步一步拆解,并针对性解决了。团队里会有技术分享会,可以学到新的技术经验。有一次我分享了一个小优化,被leader表扬了。对于一个实习生来说,这种正反馈真的很重要。生活方面…我真实地胖了五斤。公司有自己的食堂,里面还有便利店、西点房、高档咖啡厅什么的。健身房和体育馆也都有,免费游泳和健身。班车覆盖合肥市区很多线路,早晚都有。同事也都挺年轻的,茶水间会聊技术也会聊游戏,没什么那种油腻pua。午饭经常一群人端着盘子坐一块,聊着聊着就开始争论“PyTorch和TensorFlow哪个更适合做工业部署”这种话题。总的来说,这几个月确实学到了不少学校没教的东西,也见到了真正的智能制造是什么样子。他们最近举办了”联宝杯“,有机会获得校招直通绿卡,打算报名,许愿能回去!
幸运的回笼觉觉主在参...:智能制造一线实战 太羡慕了
联宝(合肥)电子科技有限公司成长空间 10人发布
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务