bzoj 1042: [HAOI2008]硬币购物【容斥原理+dp】

当然是容斥啦。

用dp预处理出\( f[i] \),表示在\( i \)价格时不考虑限制的方案数,转移方程是\( f[i]+=f[i-c[j]] \),用状压枚举不满足的状态容斥一下即可。

#include<iostream>
#include<cstdio>
using namespace std;
const long long N=100005;
long long c[10],T,d[10],s,f[N],ans;
long long read()
{
    long long r=0;
    char p=getchar();
    while(p>‘9‘||p<‘0‘)
        p=getchar();
    while(p>=‘0‘&&p<=‘9‘)
    {
        r=r*10+p-48;
        p=getchar();
    }
    return r;
}
int main()
{
    c[1]=read(),c[2]=read(),c[3]=read(),c[4]=read(),T=read();
    f[0]=1;
    for(long long j=1;j<=4;j++)
        for(long long i=1;i<=N-5;i++)
            if(i>=c[j])
                f[i]+=f[i-c[j]];
    while(T--)
    {
        ans=0ll;
        d[1]=read(),d[2]=read(),d[3]=read(),d[4]=read(),s=read();
        for(long long i=0;i<=15;i++)
        {
            long long t=1,sum=s;
            for(long long j=1;j<=4;j++)
                if(i&(1<<(j-1)))
                {
                    t=-t;
                    sum-=(d[j]+1)*c[j];
                }
            if(sum>=0)
                ans+=t*f[sum];
        }
        printf("%lld\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/lokiii/p/8215260.html

时间: 2024-11-10 11:29:42

bzoj 1042: [HAOI2008]硬币购物【容斥原理+dp】的相关文章

[BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】

题目链接:BZOJ - 1042 题目分析 首先 Orz Hzwer ,代码题解都是看的他的 blog. 这道题首先使用DP预处理,先求出,在不考虑每种硬币个数的限制的情况下,每个钱数有多少种拼凑方案. 为了避免重复的方案被转移,所以我们以硬币种类为第一层循环,这样阶段性的增加硬币. 一定要注意这个第一层循环要是硬币种类,并且初始 f[0] = 1. f[0] = 1; for (int i = 1; i <= 4; ++i) { for (int j = B[i]; j <= MaxS; +

BZOJ 1042 [HAOI2008]硬币购物 容斥原理

题意:链接 方法:容斥原理 解析:简单题,不掉坑都对不起我自己 这题很好想的一个容斥原理,因为一共只有四种硬币,我们不方便计算满足题中要求的方案数,但是从反向思考,我们需要做的就是减掉奇数个硬币用超额的情况,然后加上偶数个硬币用超额的情况就是最终的答案(当然状态是0000的时候看做是一个基准). 然后我没什么说的了,只是有一些细节需要注意下: 1.要用long long 2.完全背包千万不要傻到每次重新背,直接一次预处理就好,不过我为什么要重新背啊!(差了8s) 代码: #include <cs

bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理

题目链接 1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1706  Solved: 985[Submit][Status][Discuss] Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3

BZOJ 1042: [HAOI2008]硬币购物(容斥原理)

http://www.lydsy.com/JudgeOnline/problem.php?id=1042 题意: 思路: 如果不考虑硬币个数的话,这就是一道完全完全背包的题目. 直接求的话行不通,于是这里要用容斥原理来做. 简单来说,ans=一种没超-一种硬币超+两种硬币超-三种硬币超+四种硬币超. 1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio>

bzoj 1042 HAOI2008 硬币购物

这道题思路是在是神. 先dp出没有限制时候的方案数. dp的时候注意 先循环 1..4 再循环 1..maxs 防止重复.边界是f[0] = 1. 这么基础的背包都忘记了=_= 接下来处理有重复的问题,容斥原理     容斥原理说起来很简单,但有一些很神奇的应用,比如这道题. 最终的答案 = 没有限制的方案 - 其中一种超了限制的方案 + 其中两种超了限制的方案 - 三种超了限制的方案 + 四种超了限制的方案 ans = f[s] + f[s - c[i]*(d[i]+1)]  - ……  +

BZOJ-1042: [HAOI2008]硬币购物 (背包DP+容斥原理)

1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2888  Solved: 1777[Submit][Status][Discuss] Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,

[Luogu P1450] [HAOI2008]硬币购物 背包DP+容斥

题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包的做法. 就是对于每一次询问,我们都做一次背包. 复杂度O(tot*s*log(di)) (使用二进制背包优化) 显然会T得起飞. 接下来,我们可以换一种角度来思考这个问题. 首先,我们可以假设没有每个物品的数量的限制,那么这样就会变成一个很简单的完全背包问题. 至于完全背包怎么写,我们在这里就不做

【bzoj1042】[HAOI2008]硬币购物 背包dp+容斥原理

题目描述 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. 输入 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000 输出 每次的方法数 样例输入 1 2 5 10 2 3 2 3 1 10 1000 2 2 2 900 样例输出 4 27 题解 背包dp+容斥原理 考虑没有硬币个数限制,那么本题显然是完全

[bzoj1042][HAOI2008][硬币购物] (容斥原理+递推)

Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买si的价值的东西.请问每次有多少种付款方法. Input 第一行 c1,c2,c3,c4,tot 下面tot行 d1,d2,d3,d4,s,其中di,s<=100000,tot<=1000 Output 每次的方法数 Sample Input 1 2 5 10 2 3 2 3 1 10 1000 2 2 2 900 Sample Output 4 27 So