巨魔有金幣

巨魔有金幣


題目描述

某巨魔去了一趟拍賣行賣東西,賺了不少金幣。
該巨魔由於報復社會不成被社會報復後決定報復做題的衆人。
已知現在在WOW中有 4 種面值的金幣(我騙你們的,我說了我要報復你們!哦呵呵!),面值大小分別爲 c1c2c3c4
巨魔問你 T 次,每次詢問:當他有 si 枚面值爲 ci 的金幣時,他有多少種付錢方式買下價值爲 V 的物品,兩種付錢方式不同當且僅當兩種付錢方式中存在至少一種面值的金幣使用的數量不同。


輸入格式

第一行 5 個數字 c1c2c3c4T
接下來 T 行,每行 5 個數字,分別爲 s1s2s3s4V


輸出格式

輸出 T 行,每行一個數字,各對應一個詢問的答案。


樣例輸入

1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900


樣例輸出

4
27


數據範圍

100% 的數據 1T10001siV100000


Solution

硬幣找零


Code

#include <iostream>
#include <cstdio>

#define LL long long

using namespace std;

LL c[10],T;
LL s[10],v;

LL f[100010];

int main(){

    freopen("gold.in","r",stdin);
    freopen("gold.out","w",stdout);

    for(int i=1;i<=4;i++)scanf("%lld",&c[i]);scanf("%lld",&T);
    f[0]=1;
    for(int i=1;i<=4;i++)
        for(int j=c[i];j<=100000;j++)
            f[j]+=f[j-c[i]];
    while(T--){
        for(int i=1;i<=4;i++)scanf("%lld",&s[i]);
        scanf("%lld",&v);
        LL ans=f[v];
        for(int i=1;i<=4;i++)
            if((s[i]+1)*c[i]<=v)
                ans-=f[v-(s[i]+1)*c[i]];
        for(int i=1;i<=4;i++)
            for(int j=i+1;j<=4;j++)
                if((s[i]+1)*c[i]+(s[j]+1)*c[j]<=v)
                    ans+=f[v-(s[i]+1)*c[i]-(s[j]+1)*c[j]];
        for(int i=1;i<=4;i++)
            for(int j=i+1;j<=4;j++)
                for(int k=j+1;k<=4;k++)
                    if((s[i]+1)*c[i]+(s[j]+1)*c[j]+(s[k]+1)*c[k]<=v)
                        ans-=f[v-((s[i]+1)*c[i]+(s[j]+1)*c[j]+(s[k]+1)*c[k])];
        if((s[1]+1)*c[1]+(s[2]+1)*c[2]+(s[3]+1)*c[3]+(s[4]+1)*c[4]<=v)
            ans+=f[v-((s[1]+1)*c[1]+(s[2]+1)*c[2]+(s[3]+1)*c[3]+(s[4]+1)*c[4])];
        printf("%lld\n",ans);
    }
    return 0;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章