240101 咋提全碳

整理一下我都整了些啥。

有实际用途的是萨卡班甲鱼的勾勾(?)、巨型萨卡班甲鱼,亚克力小盒子,百万英镑的周边(迫真),东北大米草稿纸,苹果家的小镜子。

只有观赏价值的是青蛙、章鱼哥挂件、又一个章鱼哥挂件、章鱼哥超级挂件、莱伊拉和芙莉莲的立牌,abd 的风花节周边和散的透卡。

突然很好奇这么多东西我到时候要怎么搬。

多搬几趟呗。


A. 加法游戏

http://222.180.160.110:1024/contest/4626/problem/1

很厉害的一道 XSC 题,所以我 xsc062 不会做是理所当然的。

好吧开个玩笑。注意到限制次数特别小,但这个其实没起到什么提示作用。

还是有一点的。比如我们假设 \(a_{i+1}\ge 0\),两边同时加 \(a_i\),有 \(a_{i+1}+a_i\ge a_i\)

我们再假设 \(a_i\le 0\),两边同时加 \(a_{i+1}\),有 \(a_i+a_{i+1}\le a_{i+1}\)

我们有了一个思路,把整个序列的正负变成一样的,然后按照上面两种方式的任意一种从前往后 / 从后往前执行操作。

任意挑选一个正数使其 \(>20\),只需要自增就可以在 \(5\) 次操作内解决。

然后将这个正数加到所有数上面,所有数就都是正的了(花费 \(n=20\) 次操作)。做操作一得到前缀和(花费 \(n=20\) 次操作)即为答案。

如果一个正数都没有怎么办呢?那就是一个全部为非正的序列,直接做操作二得到后缀和即可。

namespace XSC062 {
using namespace fastIO;
const int maxn = 25;
int n, p, x;
int main() {
	read(n);
	for (int i = 1; i <= n; ++i) {
		read(x);
		if (x > 0) p = i;
	}
	if (p) {
		print(2 * n + 4, '\n');
		for (int i = 1; i <= 5; ++i)
			print(p, ' '), print(p, '\n');
		for (int i = 1; i <= n; ++i)
			print(i, ' '), print(p, '\n');
		for (int i = 2; i <= n; ++i)
			print(i, ' '), print(i - 1, '\n');
	}
	else {
		print(n - 1, '\n');
		for (int i = n - 1; i; --i)
			print(i, ' '), print(i + 1, '\n');
	}
	return 0;
}
} // namespace XSC062

B. 目标和

http://222.180.160.110:1024/contest/4626/problem/2

虽然说是全谈,但是。

好吧讲一讲实现技巧。把所有字面量全部加上 \(n\times V\),再把所有输入值取绝对值(因为正负无所谓),然后跑每组一正一负两个值的分组背包。

这样看来取绝对值似乎没什么意义?

#define int long long
namespace XSC062 {
using namespace fastIO;
const int maxn = 65;
const int inf = 3e5 + 4;
const int lim = 15e4 + 2;
const int maxm = 3e5 + 7;
int n, m;
int a[maxn];
int f[maxn][maxm];
int abs(int x) { return x >= 0 ? x : -x; }
int main() {
	read(n);
	for (int i = 1; i <= n; ++i)
		read(a[i]), a[i] = abs(a[i]);
	read(m), m += lim, f[0][lim] = 1;
	for (int i = 1; i <= n; ++i) {
		for (int j = 0; j <= inf; ++j) {
			if (f[i - 1][j]) {
				f[i][j + a[i]] += f[i - 1][j];
				f[i][j - a[i]] += f[i - 1][j];
			}
		}
	}
	print(f[n][m], '\n');
	return 0;
}
} // namespace XSC062
#undef int

C. 0/1 背包问题第 k 优解

http://222.180.160.110:1024/contest/4626/problem/3

就很像有序表的最小和。

\(f_{i,j}\) 表示对于 \(i\) 这个空间占用的 \(j\) 优解,然后因为 \(f_{i,1\sim k}\) 本来就是有序的,所以也没什么额外操作之类的了。

\(f_{i,1\sim k}\) 为第一个有序表,\(f_{i-V,1\sim k}+W\) 为第二个有序表,因为这个不是求和,所以用类似归并合并有序数组的方式合并之即可。

posted @ 2024-01-01 16:05  XSC062  阅读(26)  评论(0编辑  收藏  举报