「题解」洛谷 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