【NOIP2018】貨幣系統

題目鏈接

考試的時候理解錯了題目,以爲交易中是可以找零的,第一組樣例也說得通(19=10*4-3*7)。

後來發現如果這樣的話第二組樣例就錯了(13=11+19-17),我纔看到了題目中的t[i]是非負整數。

於是轉換題意,問你一個序列中最多有多少個數能被其他數表示(只能相加,每個數個數無限)。    

顯然最小的數無法被表示,於是把數列排序後從最小的數開始做完全揹包,每加入一個數就判斷一次。

極限時間複雜度O(T*N*A[i])=20*100*25000=50000000,但這是遠遠達不到的。

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
using namespace std;
int a[105],n,ans;
bool f[25005];
int main()
{
    //freopen("money.in","r",stdin);
    //freopen("money.out","w",stdout);
    int T;
    scanf("%d",&T);
    while(T--)
    {
        ans=0;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        sort(a+1,a+n+1);
        memset(f,0,sizeof(f));
        f[0]=1;
        int mx=a[n];
        for(int i=1;i<=n;i++)
        {
            if(f[a[i]])
                continue;
            ans++;
            for(int j=a[i];j<=mx;j++)
                f[j]|=f[j-a[i]];
        }
        printf("%d\n",ans);
    }
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章