bzoj 1042: [HAOI2008]硬币购物
Posted lxy8584099
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了bzoj 1042: [HAOI2008]硬币购物相关的知识,希望对你有一定的参考价值。
神奇的容斥 什么都能干
/************************************************************** Problem: 1042 User: lxy8584099 Language: C++ Result: Accepted Time:44 ms Memory:1604 kb ****************************************************************/ /* 容斥 先算出每个都不限制的背包 然后对于一个di限制 其他都不限制 个数就是 f[s-ci*(di+1)] 对于容斥 奇减偶加 */ #include<cstdio> #include<cstring> #define ll long long using namespace std; const int N=1e5+50; int c[5],tot; ll f[N]; int d[5],s; int F(int x) { return c[x]*(d[x]+1); } int main() { scanf("%d%d%d%d%d",&c[1],&c[2],&c[3],&c[4],&tot); f[0]=1; for(int i=1;i<=4;i++) for(int j=c[i];j<=100000;j++) f[j]+=f[j-c[i]]; while(tot--) { scanf("%d%d%d%d%d",&d[1],&d[2],&d[3],&d[4],&s); ll ans=f[s]; if(s-F(1)>=0) ans-=f[s-F(1)]; if(s-F(2)>=0) ans-=f[s-F(2)]; if(s-F(3)>=0) ans-=f[s-F(3)]; if(s-F(4)>=0) ans-=f[s-F(4)]; if(s-F(1)-F(2)>=0) ans+=f[s-F(1)-F(2)]; if(s-F(1)-F(3)>=0) ans+=f[s-F(1)-F(3)]; if(s-F(1)-F(4)>=0) ans+=f[s-F(1)-F(4)]; if(s-F(3)-F(2)>=0) ans+=f[s-F(3)-F(2)]; if(s-F(4)-F(2)>=0) ans+=f[s-F(4)-F(2)]; if(s-F(3)-F(4)>=0) ans+=f[s-F(3)-F(4)]; if(s-F(1)-F(2)-F(3)>=0) ans-=f[s-F(1)-F(2)-F(3)]; if(s-F(1)-F(2)-F(4)>=0) ans-=f[s-F(1)-F(2)-F(4)]; if(s-F(4)-F(2)-F(3)>=0) ans-=f[s-F(4)-F(2)-F(3)]; if(s-F(1)-F(3)-F(4)>=0) ans-=f[s-F(1)-F(3)-F(4)]; if(s-F(1)-F(2)-F(3)-F(4)>=0) ans+=f[s-F(1)-F(2)-F(3)-F(4)]; printf("%lld ",ans); } return 0; }
以上是关于bzoj 1042: [HAOI2008]硬币购物的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 1042: [HAOI2008]硬币购物 dp+容斥原理