Luogu P5020 货币系统

Luogu P5020 货币系统

题目链接

Solution

作为一道 NOIP 题,当然要考虑从部分分到正解,一是拿稳分防止正解写挂,二是可以拿不同部分分的程序对拍。

分析:看到样例大胆猜想,或者考虑这个问题的本质。

可以通过反证法证明新货币系统的集合一定是原货币系统的子集。

考虑先把 A 系统的数全部选上,然后删去一些,则这些删去的一定可以被剩下的数都表示出来,否则这个不能被新货币系统表示出来的原货币系统的数本身不能被表示出来,而这个数所拓展出去的数也不一定能被表示出来。

下面设 m=max{ai}

n13:

直接状压选哪些数,然后跑一遍 O(nm2)dp (当然实现的好的话可以做到 O(nm)),然后遍历不在当前货币系统的数,看是否能被表示出来,可以的话就更新答案。

减少常数的方法:类似最优性剪枝,如果当前的状态的二进制数本来就大于等于答案,一定不会比答案更优,可以选择不跑 dp

总时间复杂度 O(T2nnm2)O(T2nnm)

n100

毕竟和位置没有关系,所以先排一下序看看有什么结论。

这个时候发现,a1 是一定要选的,因为 a1 是最小的数,因为新货币系统中选的最小的数一定小于等于它,如果选比它更小的数,会使得比它更小的数能被新货币系统表示出来,不符合题意,所以一定选 a1

然后对于 a1,去更新它的倍数,也就是它的倍数在新货币系统中已经不需要了。然后对于后面的 ai,如果可以被前面的数表示过了,就一定不会出现在新货币系统中。否则在所有可以被表示的数上加上它的倍数去转移一个数是否能被表示出来。

时间复杂度 O(Tnm2),考虑优化,在转移的时候 modai 相等的位置会被同样的转移多次,所以只对每个不同的 modaidp 转移即可,一次转移是 mai,一共 ai 次,这样对于一个 ai 的单次转移复杂度就到 O(m) 了=w=

总时间复杂度 O(Tnm)

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
inline int Min(int x, int y) { return x < y ? x : y; }
inline int Max(int x, int y) { return x > y ? x : y; }
inline int read() {
	int r = 0; bool w = 0; char ch = getchar();
	while(ch < '0' || ch > '9') w = ch == '-' ? 1 : w, ch = getchar();
	while(ch >= '0' && ch <= '9') r = (r << 3) + (r << 1) + (ch ^ 48), ch = getchar();
	return w ? ~r + 1 : r;
}
const int N = 110;
const int K = 25010;
int n, a[N];
int b[N], cnt;
bool vis[K], vis2[K];
int main() { int T = read(); while(T--) {
	for(int i = 0; i < K; ++i) vis[i] = 0;
	cnt = 0;
	n = read();
	for(int i = 1; i <= n; ++i) a[i] = read();
	std::sort(a + 1, a + n + 1);
	if(a[1] == 1) {
		puts("1");
		continue;
	}
	for(int i = 1; i <= n; ++i) {
		if(vis[a[i]]) continue;
		b[++cnt] = a[i];
		vis[a[i]] = 1;
		for(int j = 1; j < K; ++j) {
			if(!vis[j]) continue;
			if(vis2[j % a[i]]) continue;
			for(int k = 1; k * a[i] + j < K; ++k)
				vis[k * a[i] + j] = 1;
			vis2[j % a[i]] = 1;
		}
		for(int j = 0; j < a[i]; ++j) vis2[j] = 0;
	}
	printf("%d\n", cnt);
}return 0; }
posted @   do_while_true  阅读(66)  评论(0编辑  收藏  举报
编辑推荐:
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?

This blog has running: 1845 days 1 hours 34 minutes 11 seconds

点击右上角即可分享
微信分享提示