bzoj1042[HAOI2008]硬币购物
2016-08-23 19:29
253 查看
题意就不说了,原处就说的很明白。可以明显的看出是背包问题,但多重背包问题还是有一定难度的,容斥原理与背包的应用还是第一次见,一开始并没有想到(感谢hzw)。
解法是这样的:先求出不限制硬币多少的答案数,通过容斥定理,要减去第一种硬币超过数、第二种硬币超过数、第三种硬币超过数、第四种硬币超过数,加上第一、二种硬币同时超过数、加上第一、三种硬币同时超过数、加上第一、四种硬币同时超过数、加上第二、三种硬币同时超过数、加上第二、四种硬币同时超过数、加上第三、四种硬币同时超过数………………由此类推,就将超过的都减掉了,剩下的就是答案!
恶心但好理解的for
好看的dfs
By_yzh
解法是这样的:先求出不限制硬币多少的答案数,通过容斥定理,要减去第一种硬币超过数、第二种硬币超过数、第三种硬币超过数、第四种硬币超过数,加上第一、二种硬币同时超过数、加上第一、三种硬币同时超过数、加上第一、四种硬币同时超过数、加上第二、三种硬币同时超过数、加上第二、四种硬币同时超过数、加上第三、四种硬币同时超过数………………由此类推,就将超过的都减掉了,剩下的就是答案!
恶心但好理解的for
#include<cstdio> #include<cstring> using namespace std; typedef long long LL; LL c[5],d[5],f[110000]; int main() { for(int i=1;i<=4;i++)scanf("%d",&c[i]); memset(f,0,sizeof(f));f[0]=1; for(int i=1;i<=4;i++) for(int j=c[i];j<=100000;j++) f[j]+=f[j-c[i]]; int n,s; scanf("%d",&n); while(n--) { for(int i=1;i<=4;i++)scanf("%d",&d[i]); scanf("%d",&s);LL ans=f[s]; for(int i=1; 4000 i<=4;i++) if(s>=(d[i]+1)*c[i])ans-=f[s-(d[i]+1)*c[i]]; for(int i=1;i<=3;i++) for(int j=i+1;j<=4;j++) if(s>=((d[i]+1)*c[i]+(d[j]+1)*c[j])) ans+=f[s-((d[i]+1)*c[i]+(d[j]+1)*c[j])]; for(int i=1;i<=2;i++) for(int j=i+1;j<=3;j++) for(int k=j+1;k<=4;k++) if(s>=((d[i]+1)*c[i]+(d[j]+1)*c[j]+(d[k]+1)*c[k])) ans-=f[s-((d[i]+1)*c[i]+(d[j]+1)*c[j]+(d[k]+1)*c[k])]; if(s>=((d[1]+1)*c[1]+(d[2]+1)*c[2]+(d[3]+1)*c[3]+(d[4]+1)*c[4])) ans+=f[s-((d[1]+1)*c[1]+(d[2]+1)*c[2]+(d[3]+1)*c[3]+(d[4]+1)*c[4])]; printf("%lld\n",ans); } return 0; }
好看的dfs
#include<cstdio> #include<cstring> using namespace std; typedef long long LL; LL c[5],d[5],f[110000],ans; void dfs(int x,int k,int 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-(d[x]+1)*c[x]); dfs(x+1,k,sum); } int main() { for(int i=1;i<=4;i++)scanf("%d",&c[i]); memset(f,0,sizeof(f));f[0]=1; for(int i=1;i<=4;i++) for(int j=c[i];j<=100000;j++) f[j]+=f[j-c[i]]; int n,s; scanf("%d",&n); while(n--) { for(int i=1;i<=4;i++)scanf("%d",&d[i]); scanf("%d",&s); ans=0;dfs(1,0,s); printf("%lld\n",ans); } return 0; }
By_yzh
相关文章推荐
- 【bzoj1042】 HAOI2008—硬币购物
- [BZOJ 1042] [HAOI2008] 硬币购物 【DP + 容斥】
- [bzoj1042][HAOI2008]硬币购物 容斥原理
- [bzoj1042][HAOI2008]硬币购物【dp】【容斥】
- [DP+容斥] BZOJ1042: [HAOI2008]硬币购物
- 【bzoj1042】[HAOI2008]硬币购物 背包dp+容斥原理
- bzoj1042: [HAOI2008]硬币购物
- BZOJ1042 HAOI2008硬币购物(任意模数NTT+多项式求逆+生成函数/容斥原理+动态规划)
- bzoj1042: [HAOI2008]硬币购物(Dp+容斥原理)
- 【BZOJ1042】[HAOI2008]硬币购物【计数DP】【容斥原理】
- bzoj 1042: [HAOI2008]硬币购物(容斥原理)
- BZOJ 1042:[HAOI2008]硬币购物 容斥原理 背包dp
- BZOJ1042【HAOI2008】硬币购物(DP+容斥原理)
- BZOJ 1042: [HAOI2008]硬币购物
- BZOJ1042: [HAOI2008]硬币购物
- bzoj1042 [HAOI2008]硬币购物
- 【BZOJ】1042 [HAOI2008]硬币购物 组合数学(容斥)
- 【bzoj1042】[HAOI2008]硬币购物
- BZOJ1042: [HAOI2008]硬币购物
- 【bzoj1042】 HAOI2008硬币购物 容斥原理+背包dp