D. 货币系统 (100)
Time Limit: 1s Memory Limit: 256
Description
在网友的国度中共有
n
n
n 种不同面额的货币,第
i
i
i 种货币的面额为
a
[
i
]
a[i]
a[i] ,你可以假设每一种货币都有无穷多张。为了方便,把货币种数 为
n
n
n 、面额数组为
a
[
1..
n
]
a[1 . . n]
a[1..n] 的货币系统记作
(
n
,
a
)
(n, a)
(n,a) 。
在一个完善的货币系统中,每一个非负整数的金额
x
x
x 都应该可以被表示出,即对每一个非负整数
x
x
x ,都存在
n
n
n 个非负整数
t
[
i
]
t[i]
t[i] 满足
a
[
i
]
×
t
[
i
]
a[i] \times t[i]
a[i]×t[i] 的和为
x
x
x 。然而,在网友的国度中,货币系统可能是不完善的,即可能存在金额
x
x
x 不能被该货币系统表示出。如在货币系 统
n
=
3
,
a
=
[
2
,
5
,
9
]
n=3, a=[2,5,9]
n=3,a=[2,5,9] 中,金额 1,3 就无法被表示出来。
两个货币系统
(
n
,
a
)
(n, a)
(n,a) 和
(
m
,
b
)
(m, b)
(m,b) 是等价的,当且仅当对于任意非负整数
x
x
x ,它要么均可以被两个货币系统表出,要么不能被其中任何 一个表出。
现在网友们打算简化一下货币系统。他们希望找到一个货币系统
(
m
,
b
)
(m, b)
(m,b) ,满足
(
m
,
b
)
(m, b)
(m,b) 与原来的货币系统
(
n
,
a
)
(n, a)
(n,a) 等价,且
m
m
m 尽可能 的小。他们希望你来协助完成这个艰巨的任务:找到最小的
m
m
m 。
Input Data
输入的第一行包含一个整数
T
T
T ,表示数据的组数。接下来按昭如下格式分别给出
T
T
T 组数据。 每组数据的第一行包含一个正整数
n
n
n 。接下来一行包含
n
n
n 个由空格隔开的正整数
a
[
i
]
a[i]
a[i] 。
Output Data
输出共有
T
T
T 行,对于每组数据,输出一行一个正整数,表示所有与
(
n
,
a
)
(n, a)
(n,a) 等价的货币系统
(
m
,
b
)
(m, b)
(m,b) 中,最小的
m
m
m 。
**Tips:**背包问题,看哪些价值i是不能凑出来的,这个就代表了背包容量为i的价值是1.
int Q, n, mx;
int a[115], dp[N];
signed main()
{
ios::sync_with_stdio(0), cin.tie(0);
int Q;
cin >> Q;
while (Q--)
{
memset(dp, 0xc0, sizeof(dp));
cin >> n; dp[0] = 0; mx = -INF;
for (int i = 1; i <= n; i++)
{
cin >> a[i];
mx = max(mx, a[i]);
}
for (int i = 1; i <= n; i++)
for (int j = a[i]; j <= mx; j++)
dp[j] = max(dp[j], dp[j - a[i]] + 1);
int res = 0;
for (int i = 1; i <= n; i++)
if (dp[a[i]] == 1) ++res;
cout << res << "\n";
}
return 0;
}