Codeforces Round #666 (Div. 1)

Codeforces Round #666 (Div. 1)

A-Multiples of Length

题意

给一个序列,每回可以选择一个区间,并给这个区间的每个数都减去这个区间长度的倍数(每个减去的数可以不同,但都是区间长度的倍数)。

构造一种方案使得每个位置的数都被减成 0. 并且只能选择三个区间。

题解

小清新智力题。

选择 \(1\) 到 \(n-1\) 这个区间,可以将每个数减去 \(a(n-1)\) 。

代码

B-Stoned Game

题意

有若干堆石子,每队石子有 \(a_i\) 个。现在两人玩一个游戏,每次可以在一堆石子里取 1 个,但与上回取石子的那个人不能取同一堆石子。

题解

设 \(x=\max_{i=1}^n a_i,s=\sum_{i=1}^n a_i\) ,那么若 \(x> \frac{s}{2}\) ,必是先手获胜。这时先手只要不断取最多的那堆石子就可以获胜。

下面证明 \(s\) 是偶数并且 \(x\ge\frac{s}{2}\) 的时候,必然是后手胜。

设一共有 \(s\) 个石子。如果能将这 \(s\) 个石子两两配对,那么先手拿任何一个石子,后手只要拿与之配对的棋子即可。将所有石子标上编号,那么将编号为 \(i\) 的石子与编号为 \(i+\frac{s}{2}\) 的石子配对。

C-Monster Invaders

题解

\(f_{i,0/1}\) 表示:

  • 现在在第 \(i\) 层。
  • 第 \(i-1\) 层的 Boss 的血量为 \(0/1\) 。
  • 从第 \(i\) 层开始(包含第 \(i\) 层),以后每一层都没有打过。
  • 满足以上条件打法的最小代价。

转移:

\(f_{i,0}\) 的转移:

  • 将第 \(i\) 层的小怪都用手枪杀死,并用 AWP 将 Boss 打爆。转移到 \(f_{i+1,0}\) 。
  • 将第 \(i\) 层的小怪、大怪都用 手枪/激光枪 全部打掉一滴血,并跳到 \(i+1\) 层,转移到 \(f_{i+1,1}\) 。

\(f_{i,1}\) 的转移:

  • 直接跳回 \(i-1\) 层并将第 \(i-1\) 层的 Boss 杀死,再跳回到第 \(i\) 层。转移到 \(f_{i,0}\)。
  • 先将 \(i\) 层的所有怪物都减掉一滴血(使用激光枪或手枪),再回到第 \(i-1\) 层杀死 Boss,再回来杀掉第 \(i\) 层的 Boss。此时已经将第 \(i\) 层的所有怪物都杀死,转移到 \(f_{i+1,1}\) 。

答案:

  • \(f_{n+1,0}-d\)
  • \(f_{n,0}+x\) ,其中 \(x\) 这样计算:
    • 手枪+AWP杀死第 \(n\) 层所有怪物
    • 或者 激光枪/手枪+手枪 先将第 \(n\) 层所有怪物打掉一滴血,然后跳到 \(n-1\) 层再跳回来并打死 Boss 的最小代价。

代码

#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int NN = 1e6 + 5;
int N;
ll f[NN][2], A[NN], r1, r2, r3, d;
void Upd(ll &x, ll y) {
	if (x > y)
		x = y;
}
int main() {
	scanf("%d%lld%lld%lld%lld", &N, &r1, &r2, &r3, &d);
	for (int i = 1; i <= N; ++i) scanf("%lld", &A[i]);
	memset(f, 0x3f, sizeof(f));
	f[1][0] = 0;
	for (int i = 1; i <= N; ++i) {
		Upd(f[i][0], f[i][1] + 2*d + r1);
		Upd(f[i+1][0], f[i][1] + min((A[i]+1)*r1, r2) + d + r1 + d + r1 + d);
		Upd(f[i+1][0], f[i][0] + A[i]*r1 + r3 + d);
		Upd(f[i+1][1], f[i][0] + min(r2, (A[i]+1)*r1) + d);
	}
	printf("%lld\n", min(f[N+1][0] - d, f[N][1] + r1*A[N] + r3 + d + r1));
	return 0;
}
上一篇:不愧是字节跳动技术官,算法精髓全写这本666页笔记里了,服了


下一篇:Codeforces Round #666(未完)