首页 > 其他分享 >codeforces1849 D. Array Painting

codeforces1849 D. Array Painting

时间:2024-07-07 22:52:38浏览次数:8  
标签:红色 相邻 ++ 元素 codeforces1849 int 数组 Array Painting

题目链接

https://codeforces.com/problemset/problem/1849/D


题意

输入 \(n(1 \leq n \leq 2e5)\) 和长为 \(n\) 的数组 \(a(0 \leq a[i] \leq 2)\)。

最初,数组的每个元素都是蓝色的。
有两种类型的操作:

  • 支付一枚硬币,选择一个蓝色元素,将其涂成红色。
  • 选择一个不等于 \(0\) 的红色元素和与其相邻的蓝色元素,将红色元素的数值减少 \(1\),然后将蓝色元素涂成红色。

把每个元素都涂成红色,最少要支付多少金币?

题解

先假设初始化\(a[i]\),此时我们需要支付一个金币,随后可以将其变为红色。
若\(a[i] == 0\),明显无法进行更多操作
若\(a[i] == 1\),可以选择一个相邻的蓝色元素染为红色,并且自身数字减少 \(1\)
若\(a[i] == 2\),可以选择两个相邻的蓝色元素染为红色,并且自身数字减少 \(2\)

其中最特殊的自然是0,因为\(0\)要么被一个相邻的非 \(0\) 红色元素染红,要么只能直接花费一个金币染红
贪心的思路自然是尽量使用相邻的非 \(0\) 染红,因为可以尽量少使用金币
那么思路自然是先找出一个连续非零子数组,然后再去染相邻的蓝色 \(0\)
但是先找出一个非 \(0\) 串,再去染相邻的 \(0\),显然是有点麻烦的
不妨做出如下等价转换
将数组从左往右观察,既然一个非\(0\)连续子数组可以染红一个\(0\),那么计算的数量 其实等于那些\(0\)的个数
既然如此,干脆直接从左往右计算\(0\)的个数,然后当遇到第一个连续非\(0\)子数组的时候,那个连续非\(0\)子数组都可以免费染红
如果那一串非\(0\)子数组里面全\(1\),那说明他只染了他前面那一大串\(0\)的最后一个\(0\)的位置,后面他连着的数字就不能再染,例如 \(0001110\),显然最后那个\(0\) 我们是染不到了。但是如果那个串里面有个\(2\),那么就连最后的那个\(0\)也能染了,例如 \(00021110\)。
然后什么时候一串全\(1\)子数组也能染后面的\(0\)呢?就是他前面没有任何未被染色的\(0\)的时候。举个例子,比如\(1110\),代价为\(1\),比如\(0201110\),代价为\(2\)。

参考代码

#include<bits/stdc++.h>
#define IOS ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;

int n, m;
int a[200007];

int main() {
	IOS
	cin >> n;
	for (int i{0}; i < n; ++ i) {
		cin >> a[i];
	}
	for (int i{0}, j{0}; i < n; ) {
		if (a[i] == 0) {
			j = 1;
			++ m;
			++ i;
		} else {
			if (!j) {
				++ m;
			} 
			bool flag = false;
			while (i < n && a[i] > 0) {
				if (a[i] == 2) flag = true;
				++ i;
			}
			if (flag || j == 0) ++ i; 
			j = 0;
		}
	}
	cout << m << '\n';
	return 0;
}

标签:红色,相邻,++,元素,codeforces1849,int,数组,Array,Painting
From: https://www.cnblogs.com/RomanLin/p/18281502

相关文章

  • [LeetCode] 238. Product of Array Except Self
    坑真的很多,首先要处理全零reduce没有值typeerror的问题。classSolution:defproductExceptSelf(self,nums:List[int])->List[int]:total=reduce(mul,nums)ret=[]iftotal==0:try:total=reduce(mul,[......
  • return isPlainObject(res) || Array.isArray(res) ? observer(res, cb) : res; 这个
    这段代码主要是在实现一个深度观察者模式的部分逻辑,用于递归地处理对象和数组,以便在数据结构变化时触发回调。这里的关键是理解条件运算符和函数调用的执行顺序。让我们逐步分析:条件表达式的左侧:isPlainObject(res):这个函数检查res是否是一个纯对象(即普通的JavaScript对象......
  • HashTable,ArrayList,queue等常用方法
    HashTable,ArrayList,queue等常用方法HashMap是Java中非常常用的集合类,它存储键值对,并提供了一系列方便的方法来操作这些数据。以下是一些HashMap的常用方法:1.添加和获取元素:put(key,value):将指定的键值对添加到HashMap中。如果键已存在,则更新对应的值。get(ke......
  • Arrays,Object,String,StringBuffer和常用工具类汇总
    Arrays[数组操作方法:排序,查找,替换,转换,复制]排序将数组升序排序:Arrays.sort(数组);查找数组中想查找的数字的索引:Arrays.binarysearch(数组,想查找的数字(例如3));替换将数组中的元素全部用x替换:Arrays.fill(数组,x);Arrays.fill(数组,下标y,下标z,x);//y-z下标的元素替换为x......
  • 「杂题乱刷2」CF402D Upgrading Array
    题目链接CF402DUpgradingArray(luogu)CF402DUpgradingArray解题思路首先有一个很显然的结论,就是你一旦在第\(i\)个位置上做了一次操作后,那么你之后所有在第\(j(i\lej)\)个位置做的操作都无效了,因为此时前缀的公因数为\(1\)了。因此有个很显然的结论就是操作需要......
  • Javascript中Object、Array、String
    Object在JavaScript中,Object 类型是一种复杂的数据类型,用于存储键值对集合。它提供了多种方法来操作这些键值对,以及执行其他常见的操作。这里,我列出了一些 Object 类型的常见方法或特性,它们在日常编程中非常有用:属性访问点符号(.):如果属性名是一个有效的标识符(例如,没有空格......
  • 「杂题乱刷2」CF1454F Array Partition
    题目链接CF1454FArrayPartition解题思路我们发现显然第一个和第三个区间的值区间随着长度的增大而增大。于是我们就可以枚举第一个区间的右端点位置,然后现在问题就转化成了找到一个断点来确定第二,三个区间的长度,由于前文提到的第三个区间的值区间随着长度的增大而增大,于是我......
  • ArrayList底层结构和源码分析
    //无参构造器创建ArrayList对象//ArrayListlist=newArrayList();//断点1ArrayListlist=newArrayList(8);//断点2//添加1-10数据for(inti=0;i<=10;i++){list.add(i);}//添......
  • ArrayList和LinkedList的比较
    基本比较 底层结构增删效率改查效率ArrayList可变数组较低;数组扩容较高LinkedList双向链表较高,通过链表追加较低选择使用若改查操作多选择ArrayList增删操作多选择LinkedList通常程序中大部分操作为查询,因此通常使用ArrayList根据需求,效率优先的原则......
  • torch.tensor、numpy.array、list三者之间互相转换
    torch.tensor、numpy.array、list三者之间互相转换1.1list转numpyndarray=np.array(list)1.2numpy转listlist=ndarray.tolist()2.1list转torch.Tensortensor=torch.Tensor(list)2.2torch.Tensor转list先转numpy,后转listlist=tensor.numpy().tolist(......