题意:

种面值的货币,第 种货币面值为
这组货币组成的货币系统定义为
求与 等价的货币系统 中,最小的

两个货币系统等价定义为:任意面额 ,要么均不能被两个货币系统表示出来,要么均能被表示出来。

题解:

考虑 中会存在哪些数:
考虑某个面额
不能被表示出来,那么 中肯定没有这个元素。
能被表示出来,那么这个元素必然是由 中其它元素表示出来的,所以删掉也不影响系统的表示能力,而且货币数更少。

因此 中的元素必然是 的一个子集。
:考虑 是否能由其它元素表示出来,若不能,那么 中必须要保留这个元素。若能,则可以去掉这个元素。

那么我们要做的就是考虑 中有哪些数可以有其它数表示出来。显然一个可以被其它数表示出来的值,必然大于这些数。
那么我们我们对 数组排序,然后从小到大跑一个完全背包,若 未被表示,则记入 即可。

Code:

#include <bits/stdc++.h>
using namespace std;
const int N = 25000 + 5;
int a[N], f[N], n;
int main() {
    int T; cin >> T;
    while(T--) {
        cin >> n;
        for(int i = 1; i <= n; i++) cin >> a[i];
        sort(a + 1, a + n + 1);
        memset(f, 0, sizeof f);
        f[0] = 1;
        int ans = 0;
        for(int i = 1; i <= n; i++) if(!f[a[i]]) {
            ans++;
            for(int j = a[i]; j < N; j++) f[j] |= f[j - a[i]];
        }
        cout << ans << endl;
    }
    return 0;
}