bzoj1042: [HAOI2008]硬币购物(Dp+容斥原理)
2017-11-02 15:35
393 查看
题目传送门
好强啊我根本没有往容斥原理那方面想。
解法:
先预处理出没有张数限制的方案数。
这样每一个问的答案就是:
所以方案数-第一种硬币超过限制的方案数-第二种硬币超过限制的方案数-第三种硬币超过限制的方案数-第四种硬币的方案数。
然后因为第一种硬币超过限制的方案数包含一部分第二种硬币超过限制的方案数,所以要加会一,二种硬币超过限制的方案数。
其他的同理这就是容斥原理了。。
代码实现:
好强啊我根本没有往容斥原理那方面想。
解法:
先预处理出没有张数限制的方案数。
这样每一个问的答案就是:
所以方案数-第一种硬币超过限制的方案数-第二种硬币超过限制的方案数-第三种硬币超过限制的方案数-第四种硬币的方案数。
然后因为第一种硬币超过限制的方案数包含一部分第二种硬币超过限制的方案数,所以要加会一,二种硬币超过限制的方案数。
其他的同理这就是容斥原理了。。
代码实现:
#include<cstdio> #include<cstring> #include<cstdlib> #include<iostream> #include<algorithm> #include<cmath> #include<queue> using namespace std; typedef long long ll; ll f[110000]; ll c[5],d[5],s; ll ans; void dfs(int x,int k,ll sum) { if(sum<0) return ; if(x==5) { if(k%2==1) ans-=f[sum]; else ans+=f[sum]; return ; } dfs(x+1,k+1,sum-c[x]*(d[x]+1)); dfs(x+1,k,sum); } int main() { for(int i=1;i<=4;i++) scanf("%lld",&c[i]); memset(f,0,sizeof(f)); f[0]=1;int T;scanf("%d",&T); 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",&d[i]); scanf("%lld",&s); ans=0;dfs(1,0,s); printf("%lld\n",ans); } return 0; }
相关文章推荐
- 【BZOJ】1042: [HAOI2008]硬币购物(dp+容斥原理)
- BZOJ1042【HAOI2008】硬币购物(DP+容斥原理)
- [BZOJ1042][HAOI2008]硬币购物 (DP+容斥原理)
- BZOJ1042: [HAOI2008]硬币购物 dp+容斥原理
- 【bzoj 1042】 [HAOI2008] 硬币购物(dp+容斥原理)
- 【bzoj1042】[HAOI2008]硬币购物 背包dp+容斥原理
- 【bzoj1042】【HAOI2008】【硬币购物】【dp+容斥原理】
- [BZOJ1042][HAOI2008]硬币购物(dp+容斥原理)
- bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理
- 【bzoj1042】 HAOI2008—硬币购物
- bzoj 1042: [HAOI2008]硬币购物(容斥原理)
- BZOJ 1042: [HAOI2008]硬币购物
- [BZOJ1042]HAOI2008硬币购物|DP|容斥原理
- bzoj1042: [HAOI2008]硬币购物 容斥原理
- bzoj1042 [HAOI2008]硬币购物
- [bzoj 1042][HAOI2008]硬币购物(用容斥原理弄背包)
- BZOJ 1042 [HAOI2008]硬币购物
- BZOJ 1042: [HAOI2008]硬币购物( 背包dp + 容斥原理 )
- BZOJ 1042: [HAOI2008]硬币购物(容斥原理)
- bzoj1042 [HAOI2008]硬币购物