首页 > 其他分享 >Milena and Admirer

Milena and Admirer

时间:2023-11-22 19:56:55浏览次数:32  
标签:cnt Milena int ll 分解 数组 Admirer 最优

引言

题目链接:https://codeforces.com/contest/1898/problem/B

思路

首先根据题目要求,要求操作后的数组是非递减数组,所以只能从后向前遍历数组进行操作

对于当前需要进行操作的 \(a_i\) 来说一定是使其分解出来的数尽可能相等的做法是最优方案

那么对于 \(a_i,a_{i+1}\) 来说,假设 \(a_i > a_{i + 1}\)

我们要对 \(a_i\) 进行操作,则需要将其分解成 \(cnt = \lceil \frac{a_i}{a_{i + 1}} \rceil\) 个数才能保证对于每个分解出的数尽可能相等且都小于 \(a_{i + 1}\)

将其分解成 cnt - 1 块后,最小的数放在最左边

该数为 \(\lfloor \frac{a_i}{cnt} \rfloor\)

例:
\(a_i=10,a_{i+1}=4\)

一种方案是将 \(a_i\) 分解为 2,4,4

这显然不是最优方案

其最优方案一定是将 \(a_i\) 分解为 3,3,4

代码

#include <bits/stdc++.h>
#define ll long long
#define N 200100

ll a[N];

void solve() {
	int n;
	std::cin >> n;
	for (int i = 1 ; i <= n ; i ++ ) {
		std::cin >> a[i];
	}

	ll res = 0;
	ll now = a[n];
	for (int i = n - 1 ; i >= 1 ; i -- ) {
		if(a[i] <= now) {
			now = a[i];
		}
		else {
			ll cnt = (a[i] + now - 1) / now;
			res += cnt - 1;
			now = a[i] / cnt;
		}
	}

	std::cout << res << "\n";
}

int main() {
	int t;
	std::cin >> t;
	while(t -- ) {
		solve();
	}
	return 0;
}

标签:cnt,Milena,int,ll,分解,数组,Admirer,最优
From: https://www.cnblogs.com/NachoNeko/p/17850145.html

相关文章

  • CF1898 B Milena and Admirer 题解
    LinkCF1898BMilenaandAdmirerQuestion给出一个长度为\(n\)的序列\(a\),我们可以做一种操作使得\(a\)非降,操作是:对于一个\(a_i\)选择一个整数\(0\lex\lea_i\),用两个数\(x,(a_i-x)\)来替换\(a_i\)。求最小操作次数。Solution考虑哪些数是需要操作的,如......