NOIP2018 貨幣系統
阿新 • • 發佈:2019-04-24
空格 () ext mar time ++ 我們 c++ 希望
貨幣系統
Description
在網友的國度中共有n種不同面額的貨幣,第i種貨幣的面額為a[i],你可以假設每一種貨幣都有無窮多張。為了方便,我們把貨幣種數為n、面額數組為a[1…n]的貨幣系統記作(n,a)。
在一個完善的貨幣系統中,每一個非負整數的金額xx都應該可以被表示出,即對每一個非負整數x,都存在n個非負整數t[i]滿足a[i]×t[i]的和為x。然而, 在網友的國度中,貨幣系統可能是不完善的,即可能存在金額x不能被該貨幣系統表示出。例如在貨幣系統n=3,a=[2,5,9]中,金額1,3就無法被表示出來。
兩個貨幣系統(n,a)和(m,b)是等價的,當且僅當對於任意非負整數x,它要麽均可以被兩個貨幣系統表出,要麽不能被其中任何一個表出。
現在網友們打算簡化一下貨幣系統。他們希望找到一個貨幣系統(m,b),滿足(m,b)與原來的貨幣系統(n,a)等價,且m盡可能的小。他們希望你來協助完成這個艱巨的任務:找到最小的m。
Input
輸入的第一行包含一個整數T,表示數據的組數。
接下來按照如下格式分別給出T組數據。 每組數據的第一行包含一個正整數n。接下來一行包含n個由空格隔開的正整數a[i]。
Output
輸出文件共有T行,對於每組數據,輸出一行一個正整數,表示所有與(n,a)等價的貨幣系統(m,b)中,最小的m。
Sample Input 1
2 4 3 19 10 6 5 11 29 13 19 17
Sample Output 1
2 5
Hint
對於全部數據,滿足1≤T≤20,n,a[i]≥1。
Source
NOIP2018
和上個音量調節類似。剛開始題目意思沒懂。只要存在a[任意]*r+a[任意]*s=x即可,所以可以從小到達排序,然後“去重“。 3 :可以篩掉 3 6 9 12 15 18 6 :被篩過 10:可以篩掉 10 13 16 19 19:被篩過1 #include<bits/stdc++.h> 2using namespace std; 3 const int M=25100; 4 5 int a[110]; 6 bool dp[M]; 7 8 int main() { 9 int _; 10 for(scanf("%d",&_);_;_--) { 11 int n; 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) scanf("%d",&a[i]); 14 memset(dp,false,sizeof(dp)); 15 dp[0]=true;//初始條件 16 sort(a+1,a+n+1); 17 int ans=0; 18 for(int i=1;i<=n;i++) { 19 if(dp[a[i]]) continue; 20 ans++; 21 for(int j=a[i];j<M;j++) { 22 dp[j]|=dp[j-a[i]];//當前是3 ,0是否出現 若 23 } //若出現標記3 24 } 25 printf("%d\n",ans); 26 } 27 }
NOIP2018 貨幣系統