巨魔有金币

69 篇文章 0 订阅

巨魔有金币


题目描述

某巨魔去了一趟拍卖行卖东西,赚了不少金币。
该巨魔由于报复社会不成被社会报复后决定报复做题的众人。
已知现在在WOW中有 4 种面值的金币(我骗你们的,我说了我要报复你们!哦呵呵!),面值大小分别为 c1 c2 c3 c4
巨魔问你 T 次,每次询问:当他有 si 枚面值为 ci 的金币时,他有多少种付钱方式买下价值为 V 的物品,两种付钱方式不同当且仅当两种付钱方式中存在至少一种面值的金币使用的数量不同。


输入格式

第一行 5 个数字 c1 c2 c3 c4 T
接下来 T 行,每行 5 个数字,分别为 s1 s2 s3 s4 V


输出格式

输出 T 行,每行一个数字,各对应一个询问的答案。


样例输入

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


样例输出

4
27


数据范围

100% 的数据 1T1000 1si V100000


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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值