可以看出这是个多重背包,运用单调队列优化可以使每次询问达到O(s).这样总复杂度为O(s*tot). 会TLE. 因为改题的特殊性,每个硬币的币值是不变的,变的只是每次询问的硬币个数. 我们不妨不考虑硬币个数的限制.这样可以用完全背包在O(s)的时间求出dp[]数组,表示没有限制的种数. 现在加入每个硬币的限制后,由于容斥原理,答案就是没有限制的种数-第一个硬币的限制种数-第二个硬币限制种数...... 如果加入第一个硬币的限制后怎么求呢.就相当于你先把第一个硬币用到刚超过限制,剩下的随便怎么选…
先按完全背包做一次dp, dp(x)表示x元的东西有多少种方案, 然后再容斥一下. ------------------------------------------------------------------------ #include<cstdio> #include<algorithm> #include<cstring>   using namespace std;   typedef long long ll;   const int maxn = 1…
题解: 计数题 首先考虑容斥 这题很明显加了限制状态就很多 考虑没有限制 显然可以直接dp 然后 我们看一下 容斥 某一个使用>=k张 那么其实就是 f[i-k*c[]] 于是这样就可以做了…
http://www.lydsy.com/JudgeOnline/problem.php?id=1042 一开始写了个O(nv)的背包,果断tle... 看了题解,,好神..用了组合数学中的多重集合方案的容斥原理. 设$A_i$表示i超过d[i]的性质 则我们要求: $$| \overline{A_1} \cap \overline{A_2} \cap ... \cap \overline{A_n} |$$ 而我们可以根据容斥求出这个值,即: $$| \overline{A_1} \cap \o…
题面 传送门:https://www.luogu.org/problemnew/show/P1450 Solution 这是一道很有意思的在背包里面做容斥的题目. 首先,我们可以很轻松地想到暴力做背包的做法. 就是对于每一次询问,我们都做一次背包. 复杂度O(tot*s*log(di)) (使用二进制背包优化) 显然会T得起飞. 接下来,我们可以换一种角度来思考这个问题. 首先,我们可以假设没有每个物品的数量的限制,那么这样就会变成一个很简单的完全背包问题. 至于完全背包怎么写,我们在这里就不做…
失踪OJ回归. 小C通过这道题mark一下容斥一类的问题. Description 硬币购物一共有4种硬币.面值分别为c1,c2,c3,c4.某人去商店买东西,去了tot次.每次带di枚ci硬币,买s的价值的东西.请问每次有多少种付款方法. 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…
题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1042 题意:给出四种面值的硬币c1,c2,c3,c4.n个询问.每次询问用d1.d2.d3.d4个相应的硬币能够拼出多少种总和为s? 思路:(1)首先,用完全背包求出f[i]表示四种硬币的数量无限制拼出i的方案数. (2)接着我们来理解 x=f[s]-f[s-(d1+1)*c1]的含义:x表示c1硬币的数量不超过d1个而其他三种硬币的数量不限制拼成s的方案数.我们举着例子来说明, 假设…
先不考虑限制,那么有dp[i]表示i元钱的方案数. 然后考虑限制,发现可以容斥. 其实整个题就是两个容斥原理.感觉出的蛮好的. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100500 using namespace std; ],d[],n,s,ans; void pre_dp() { f[]=; ;i<=maxn-;i+…
题目链接: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; +…
题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1042 分析: 解法很巧妙,用f[i]表示四种硬币A.B.C.D的数量不考虑的情况下弄成面值i的方案数(即完全背包) 然后对于每个询问用容斥原理: ans(A.B.C.D均不超过限制的方案数)=A.B.C.D均超过限制的方案数-A超过限制的方案数-B超过限制的方案数-C超过限制的方案数+A.B超过限制的方案数+A.C超过限制的方案数…… 至于“超过限制的方案数”怎么表示:举个例子,假设…