P5020 货币系统 题解

原题链接

简要题意:

求一个长度最小的货币系统与给出的货币系统等价。求这个货币系统的长度。等价的定义详见题目,不再赘述。

本文可能用到一些集合论,请放心食用。

算法一

\(n=2\) 时,只需判断两个数的倍数关系。有倍数关系则答案为 \(1\),否则为 \(2\).

时间复杂度:\(O(T \times n)\).

实际得分:\(15pts\).

算法二

\(n=3\) 时,首先,如果两个数都是另一个数的倍数,那么答案为 \(1\).

否则,如果仍存在倍数关系,则答案为 \(2\).

其余的情况,只需要考虑,最小的数和次小的数能否表示出最大的数。

能则为 \(2\),否则为 \(3\).

这里有很多种方法判断。比如:

  1. 暴力,用桶直接来,\(O(\max a_i)\).

  2. 考虑解方程,用 \(\texttt{exgcd}\) 写,\(O(\log \max a_i)\).

总之,时间复杂度为 \(O(T \times n \times (\max a_i))\). (无需优化,因为没有必要)

实际得分:\(30pts\).

算法三

首先,假设给出 \(S\),答案为 \(T\). 则必有:

\[T \in S \]

下面来证明这个结论。

如果 \(T \not \in S\),则考虑取出 \(x = \min (i \in S)\)\(y = \min(i \in T)\).

如果 \(x<y\),则 \(x\) 无法被表示。

如果 \(y>x\),则 \(y\) 无法被表示。

如果 \(x=y\),那么不断递归下去,得证。

所以,我们只需要在给出的货币系统中寻找答案即可。

这里我们枚举选的答案,然后一一验证。

时间复杂度:\(O(2^n \times n \times (\max a_i) \times T)\),可以通过。

实际得分:\(65pts\).

算法四

注: \(n = 25\),本人没有想到什么可以 \(O(2^n \times T)\) 过掉的算法,因此这一档部分分可能是用来给选手瞎搞的。???

你发现不需要一一枚举。首先你排序一下。

你只要用当前已有的数,判断当前正在决策的这个数能否被表示出。

能,那么说明这个数没有必要,把它抛弃。

否则,肯定要选。只是因为,\(>\) 它的数表示不出,而 \(<\) 也表示不出,只有它自己能表示自己,所以必须选。

那么,这样我们可以唯一确定一个数是否被选。(排序后从小到大选)

如何判断?

我们发现,每次新加入一个数 \(x\) ,我们需要维护能判断出的桶。

此时,可以在原有的桶上,对每个能表示出的数 \(k\),把 \(k+x , k+2x,k+3x \cdots k+ \infty x\) 全部标为可以判断。这是显然的。

至于 \(\infty\) 的上限,只要标到 \(\max a_i\) 即可,因为后面的数没有用了。

时间复杂度:\(O(n \times T \times (\max a_i))\).

实际得分:\(100pts\).

#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;

const int N=5e4+1;

inline int read(){char ch=getchar();int f=1;while(ch<'0' || ch>'9') {if(ch=='-') f=-f; ch=getchar();}
	int x=0;while(ch>='0' && ch<='9') x=(x<<3)+(x<<1)+ch-'0',ch=getchar();return x*f;}

int T,n,a[N];
int cnt=0;
int maxi; bool h[N];

int main(){
	T=read(); while(T--) {
		n=read(); maxi=0; cnt=0;
		memset(h,0,sizeof(h)); //初始化
		for(int i=1;i<=n;i++) a[i]=read(),maxi=max(maxi,a[i]);
		sort(a+1,a+1+n); //排序
		for(int i=1;i<=n;i++)
			if(!h[a[i]]) { //不能被表示
				h[a[i]]=1; cnt++;
				for(int j=1;j<=maxi;j++)
					if(h[j]) {
						for(int k=a[i];j+k<=maxi;k+=a[i])
							h[j+k]=1;
					} //维护能被表示的桶
			} printf("%d\n",cnt);
	}
	return 0;
}

猜你喜欢

转载自www.cnblogs.com/bifanwen/p/12576482.html
今日推荐