【题目链接】

点击打开链接

【算法】

此题是一道好题!

首先,我们发现 : 付款方法数 = 不受限制的方法数 - 受限制的方法数

那么,我们怎么求呢?

我们用dp求出不受限制的方法数(f[i]表示买i元的东西,不受硬币限制,有多少种方案),只需用01背包的

方法就可以了,实现非常简单

那么受限制的方法数怎么求呢?由容斥原理可知,受限制的方法数 = 第一种硬币超限 + 第二种硬币超限 + ...

- 第一,二,三,四种硬币超限

第一种硬币超限,其实就是先选(d1 + 1)枚第一种硬币,其他随便选,那么对应的数量就是

f[s - (d1 + 1) * c[1]],其他情况类似,注意当减下来小于零时是不可以的

于是,这道题便迎刃而解了!

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXS 100010 long long i,j,d1,d2,d3,d4,T,s;
long long c[];
long long ans;
long long f[MAXS]; int main()
{ scanf("%lld%lld%lld%lld%lld",&c[],&c[],&c[],&c[],&T);
f[] = ;
for (i = ; i <= ; i++)
{
for (j = c[i]; j < MAXS; j++)
{
f[j] += f[j-c[i]];
}
}
while (T--)
{
scanf("%lld%lld%lld%lld%lld",&d1,&d2,&d3,&d4,&s);
ans = f[s];
if (s - (d1 + ) * c[] >= ) ans -= f[s - (d1 + ) * c[]];
if (s - (d2 + ) * c[] >= ) ans -= f[s - (d2 + ) * c[]];
if (s - (d3 + ) * c[] >= ) ans -= f[s - (d3 + ) * c[]];
if (s - (d4 + ) * c[] >= ) ans -= f[s - (d4 + ) * c[]];
if (s - (d1 + ) * c[] - (d2 + ) * c[] >= ) ans += f[s - (d1 + ) * c[] - (d2 + ) * c[]];
if (s - (d1 + ) * c[] - (d3 + ) * c[] >= ) ans += f[s - (d1 + ) * c[] - (d3 + ) * c[]];
if (s - (d1 + ) * c[] - (d4 + ) * c[] >= ) ans += f[s - (d1 + ) * c[] - (d4 + ) * c[]];
if (s - (d2 + ) * c[] - (d3 + ) * c[] >= ) ans += f[s - (d2 + ) * c[] - (d3 + ) * c[]];
if (s - (d2 + ) * c[] - (d4 + ) * c[] >= ) ans += f[s - (d2 + ) * c[] - (d4 + ) * c[]];
if (s - (d3 + ) * c[] - (d4 + ) * c[] >= ) ans += f[s - (d3 + ) * c[] - (d4 + ) * c[]];
if (s - (d1 + ) * c[] - (d2 + ) * c[] - (d3 + ) * c[] >= ) ans -= f[s - (d1 + ) * c[] - (d2 + ) * c[] - (d3 + ) * c[]];
if (s - (d1 + ) * c[] - (d2 + ) * c[] - (d4 + ) * c[] >= ) ans -= f[s - (d1 + ) * c[] - (d2 + ) * c[] - (d4 + ) * c[]];
if (s - (d1 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[] >= ) ans -= f[s - (d1 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[]];
if (s - (d2 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[] >= ) ans -= f[s - (d2 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[]];
if (s - (d1 + ) * c[] - (d2 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[] >= ) ans += f[s - (d1 + ) * c[] - (d2 + ) * c[] - (d3 + ) * c[] - (d4 + ) * c[]];
printf("%lld\n",ans);
} return ;
}

【HAOI 2008】 硬币购物的更多相关文章

  1. [HAOI 2008]硬币购物

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

  2. 【BZOJ-1042】硬币购物 容斥原理 + 完全背包

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1811  Solved: 1057[Submit][Stat ...

  3. bzoj1042: [HAOI2008]硬币购物

    #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #i ...

  4. 【BZOJ】【1042】【HAOI2008】硬币购物

    DP+容斥原理 sigh……就差一点…… 四种硬币的数量限制就是四个条件,满足条件1的方案集合为A,满足条件2的方案集合为B……我们要求的就是同时满足四个条件的方案集合$A\bigcap B\bigc ...

  5. 1042: [HAOI2008]硬币购物 - BZOJ

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

  6. 【BZOJ1042】【DP + 容斥】[HAOI2008]硬币购物

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

  7. Bzoj 1042: [HAOI2008]硬币购物 容斥原理,动态规划,背包dp

    1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1747  Solved: 1015[Submit][Stat ...

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

    题目链接 1042: [HAOI2008]硬币购物 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1706  Solved: 985[Submit][ ...

  9. BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )

    先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ---------------------------------------------------------- ...

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

    1042: [HAOI2008]硬币购物 题意:4种硬币.面值分别为c1,c2,c3,c4.1000次询问每种硬币di个,凑出\(s\le 10^5\)的方案数 完全背包方案数? 询问太多了 看了题解 ...

随机推荐

  1. 第八届河南省程序设计大赛-B.最大岛屿0000110011000000

    最大岛屿                                                                                           时间限制: ...

  2. OSPF选路原则

    1:O路由>Oia路由>external路由! O:计算LSA-1和LSA-2,前提age不能MaxAge,metric不能LSinfinity,计算出来的最小metric的路由放入RIB ...

  3. ubuntu samba 配置简介

    Ubuntu 11.04下虚拟机Samba的共享配置详细步骤 一. Ubuntu 11.04下Samba的安装: $ sudo apt-get insall samba                 ...

  4. Error:Uninitialized object exists on backward branch 70 Exception Details:

    网上下载了一个demo,编译出现如下错误: Gradle sync failed: Uninitialized object exists on backward branch 70 Exceptio ...

  5. hdu 5200 Trees [ 排序 离线 2指针 ]

    传送门 Trees  Accepts: 156  Submissions: 533  Time Limit: 2000/1000 MS (Java/Others)  Memory Limit: 655 ...

  6. codeforces 1041 d 二分

    题意转化:有一些区间,要求选一些连续的区间.两两区间间隔的和要求小于H.要求区间的长度和尽可能长. 二分区间长度的和,check一下就行 #include <bits/stdc++.h> ...

  7. Knockout.js用jquery的val设置值不更新

    用如下方法,加上change() .val("blah").change()

  8. Go和HTTPS(TLS)

    原文链接: http://studygolang.com/wr?u=http%3a%2f%2ftonybai.com%2f2015%2f04%2f30%2fgo-and-https%2f 近期在构思一 ...

  9. 项目中遇到的HQL查询问题

    问题描写叙述: 目的:想要查询出全部最新版本号的组件 说明:组件:版本号 =1:n关系 ,假设这个组件仅仅有一个版本号也要可以查出来. 项目中使用的是内存数据库,无法看到表结构,这里的样例仅仅用于模拟 ...

  10. Android sdcard读写权限问题之中的一个

    博主在刚刚在学习过程中发现了一个关于android往sdcard读写的问题, 配置了该配置的提示无读写权限. 在AndroidManifest.xml文件里配置清单例如以下 <manifest ...