【bzoj1042】[HAOI2008]硬币购物【dp预处理+容斥】

传送门:

http://www.lydsy.com/JudgeOnline/problem.php?id=1042

思路:

参考这篇 : http://hzwer.com/5286.html

代码:

#include <set>
#include <map>
#include <queue>
#include <vector>
#include <math.h>
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <string.h>
using  namespace  std;

#define ff first
#define ss second
#define pb push_back
#define ll long long
#define mod 1000000007
#define ull unsigned long long
#define mst(ss,b) memset(ss,b,sizeof(ss));
#define pl(x) cout << #x << "= " << x << endl;
const int inf = 0x3f3f3f3f;
const int N = 1e5+5;

int c[N], d[N];
ll f[N], ans;

void dfs(int cur, int x, int sum){
    if(sum<0)return ;

    if(cur == 5){
        if(x&1)ans -= f[sum];
        else ans += f[sum];
        return ;
    }

    dfs(cur+1, x+1, sum-(d[cur]+1)*c[cur]);
    dfs(cur+1, x, sum);
}

int  main(){
    int T;
    for(int i=1; i<=4; i++)scanf("%d", &c[i]);
    scanf("%d", &T);
    f[0] = 1;
    for(int i=1; i<=4; i++)
        for(int j=c[i]; j<N; j++)f[j] += f[j-c[i]];
    while(T--){
        ans = 0;
        for(int i=1; i<=4; i++)scanf("%d", &d[i]);
        int s;
        scanf("%d", &s);
        dfs(1, 0, s);
        printf("%lld\n", ans);
    }
    return 0;
}

描述:

【bzoj1042】[HAOI2008]硬币购物
2014年11月30日2,7282
Description

硬币购物一共有4种硬币。面值分别为c1,c2,c3,c4。某人去商店买东西,去了tot次。每次带di枚ci硬币,买si的价值的东西。请问每次有多少种付款方法。

Input

第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s

Output

每次的方法数

Sample Input

1 2 5 10 2
3 2 3 1 10
1000 2 2 2 900
Sample Output

4
27
HINT

数据规模
di,s<=100000
tot<=1000

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值