Atcoder ARCaea 118 B

我又来啦!
光 & 对立

题面

小 A 正在调配药剂。
传说中有一种最强的药剂,叫做 Tempestissimo ,用了 $ K $ 种药剂,标号 $ 1 \sim K $ 。
当时(由于这药剂只调配过一次)分别用了 $ A_1, A_2, A_3, \cdots, A_K $ 毫升。(注:总共是 $ N $ 毫升)
现在,小 A 有 $ M $ 毫升可转换为任何一种液体的液体(好神奇!),他想调配出这种药剂,
可惜……可惜 $ < 1 $ 毫升的部分将会爆炸(?),所以每种都只能变整数毫升。
小 A 想请你来帮他决定最佳值($ B_1, B_2, B_3, \cdots, B_K $)毫升(注:小 A 想把 $ M $ 毫升全用完),使得 $ \max_{i} | \frac{A_i}{N} - \frac{B_i}{M} | $ 最小(即调配出来的药剂最接近 Tempestissimo)。
你能完成吗?
话说这翻译与原题差异简直太大了

解法

回忆率:简单 - 音符流失后的回忆率丢失程度减小
显然,我们的 $ B_i $ 就应该按照 $ A_i $ 的比例去调配。
则 $ B_i = \frac{A_iM}{N} $ 。
但你这 $ B_i $ 是小数啊!
那就……

\[B_i = \lfloor \frac{A_iM}{N} \rfloor \]

然后,和不够 $ M $ 怎么办?
回忆率:困难 - 回忆率归零后直接判定为乐曲失败
那就取 $ A_iM \bmod N $ ,排序,从大到小排
然后从前往后,依次加 1。
至于为什么你们自己想吧,反正我是 DL(D + Track Lost)了。

代码

#include <bits/stdc++.h>
using namespace std;

long long a[100005];
long long b[100005];
vector<pair<long long, int> > mods;

int main() {
	int k;
	long long n, m;
	scanf("%d %lld %lld", &k, &n, &m);
	for (int i = 0; i < k; i++) {
		scanf("%lld", &a[i]);
	}
	long long sum = 0;
	for (int i = 0; i < k; i++) {
		b[i] = a[i] * m / n;
		sum += b[i];
		mods.emplace_back(a[i] * m % n, i);
	}
	long long diff = m - sum;
	sort(mods.begin(), mods.end(), greater<pair<int, int> >());
	for (int i = 0; i < diff; i++) {
		b[mods[i].second]++;
	}
	for (int i = 0; i < k; i++) {
		printf("%lld ", b[i]);
	}
	return 0;
}
posted @ 2022-11-12 17:00  A-Problem-Solver  阅读(36)  评论(0编辑  收藏  举报