題目描述
在網友的國度中共有 nn 種不同面額的貨幣,第 ii 種貨幣的面額為 a[i]a[i],你可以假設每一種貨幣都有無窮多張。為了方便,我們把貨幣種數為 nn、面額數組為 a[1..n]a[1..n] 的貨幣系統記作 (n,a)(n,a)。
在一個完善的貨幣系統中,每一個非負整數的金額 xx 都應該可以被表示出,即對每一個非負整數 xx,都存在 nn 個非負整數 t[i]t[i] 滿足 a[i] \times t[i]a[i]×t[i] 的和為 xx。然而, 在網友的國度中,貨幣系統可能是不完善的,即可能存在金額 xx 不能被該貨幣系統表示出。例如在貨幣系統 n=3n=3, a=[2,5,9]a=[2,5,9] 中,金額 1,31,3 就無法被表示出來。
兩個貨幣系統 (n,a)(n,a) 和 (m,b)(m,b) 是等價的,當且僅當對於任意非負整數 xx,它要么均可以被兩個貨幣系統表出,要么不能被其中任何一個表出。
現在網友們打算簡化一下貨幣系統。他們希望找到一個貨幣系統 (m,b)(m,b),滿足 (m,b)(m,b) 與原來的貨幣系統 (n,a)(n,a) 等價,且 mm 盡可能的小。他們希望你來協助完成這個艱巨的任務:找到最小的 mm。
輸入格式
輸入文件的第一行包含一個整數 TT,表示數據的組數。
接下來按照如下格式分別給出 TT 組數據。 每組數據的第一行包含一個正整數 nn。接下來一行包含 nn 個由空格隔開的正整數 a[i]a[i]。
輸出格式
輸出文件共有 TT 行,對於每組數據,輸出一行一個正整數,表示所有與 (n,a)(n,a) 等價的貨幣系統 (m,b)(m,b)中,最小的 mm。
輸入輸出樣例
2 4 3 19 10 6 5 11 29 13 19 17
2 5
說明/提示
在第一組數據中,貨幣系統 (2, [3,10])(2,[3,10]) 和給出的貨幣系統 (n, a)(n,a) 等價,並可以驗證不存在 m < 2m<2 的等價的貨幣系統,因此答案為 22。 在第二組數據中,可以驗證不存在 m < nm<n 的等價的貨幣系統,因此答案為 55。
【數據范圍與約定】

對於 100\%100% 的數據,滿足 1 ≤ T ≤ 20, n,a[i] ≥ 11≤T≤20,n,a[i]≥1。
題解:原來去年題目這么水!!!蠻簡單的呀QAQ。就是類似於篩法。
把一些不必要的金錢都舍掉,比如有3,則6,9,12都是多余的,先排序
從小到大枚舉。則大的肯定會被小的篩掉,最后看有多少個“必要金錢”即可。
#include<cstdio> #include<iostream> #include<cmath> #include<cstring> #include<cstdlib> #include<algorithm> #include<queue> using namespace std; const int N=103; int Yao_Chen,n,ans,mx; int a[N],f[25005]; int main(){ freopen("5020.in","r",stdin); freopen("5020.out","w",stdout); scanf("%d",&Yao_Chen); while(Yao_Chen--){ scanf("%d",&n); ans=0; mx=0; memset(f,0,sizeof(f)); for(int i=1;i<=n;i++){ scanf("%d",&a[i]); mx=max(mx,a[i]); f[a[i]]=2; } sort(a+1,a+n+1); for(int i=1;i<=mx;i++){ if(f[i]>0){ for(int j=1;j<=n;j++){ if(i+a[j]<=mx) f[i+a[j]]=1; else break; } } } for(int i=1;i<=mx;i++) if(f[i]==2) ans++; printf("%d\n",ans); } return 0; }
