其他分享
首页 > 其他分享> > 「题解」洛谷 P5020 货币系统

「题解」洛谷 P5020 货币系统

作者:互联网

题目

P5020 货币系统

简化题意

给你一个集合 \(A\),让你找到元素最少的和集合 \(A\) 等价的集合 \(B\)。

等价指的是用 \(A\) 中元素能表出的使用 \(B\) 中元素也能表出,用 \(A\) 中元素不能表出的使用 \(B\) 中元素也不能表出。

题解

dp。本题的答案就是 \(A\) 中不能被 \(A\) 中其它元素表出的元素的个数。

证明:

先证明 \(A\) 中不能被 \(A\) 中其它元素表出的元素一定在 \(B\) 中。

反证法。若 \(x \in A\) 并且 \(x\) 不能被 \(A\) 中其它元素表出。设 \(x \notin B\)。

因为 \(A\) 和 \(B\) 是等价的,所以 \(B\) 中一定存在 \(b_1,b_2,\dots b_k\) 可以表出 \(x\)。然后 \(A\) 中一定存在元素可以表出 \(b_1,b_2,\dots, b_k\),那么 \(x\) 可以由 \(A\) 中元素表出,与事实不符。证毕。

再证明 \(A\) 中能被 \(A\) 中其它元素表出的元素一定不在 \(B\) 中。

反证法。若 \(x \in A\) 并且 \(x\) 能被 \(a_1,a_2,\dots,a_k\) 表出。设 \(x \in B\)。
因为 \(A\) 和 \(B\) 是等价的,所以 \(B\) 中元素可以表出 \(a_1,a_2,\dots,a_k\),也就可以表出 \(x\)。与 \(B\) 中元素尽量少的事实不符。证毕。

Code

#include <cstdio>
#include <cstring>
#include <string>
#include <iostream>
#include <algorithm>
#define M 25001

int t, n, ans, a[101], f[M];

int main() {
    scanf("%d", &t);
    while (t--) {
        memset(f, 0, sizeof f);
        scanf("%d", &n), ans = n, f[0] = 1;
        for (int i = 1; i <= n; ++i) scanf("%d", &a[i]);
        std::sort(a + 1, a + n + 1);
        for (int i = 1; i <= n; ++i) {
            if (f[a[i]]) --ans;
            else {
                for (int j = a[i]; j <= a[n]; ++j) {
                    f[j] |= f[j - a[i]];
                }
            }
        }
        printf("%d\n", ans);
    }
    return 0;
}

标签:表出,dots,洛谷,int,题解,元素,等价,P5020,include
来源: https://www.cnblogs.com/poi-bolg-poi/p/13661761.html