洛谷1450-HAOI硬币购物题解-容斥原理
1450-HAOI硬币购物
考虑不记d[i]限制的情况,其实就是裸的完全背包。
\[dp[i]=∑dp[i-k*c[i]]
\]
完全背包的优化:
\[dp[i]+=dp[i-c[i]]
\]
对于四种硬币跑四轮即可。时间复杂度O(4e5)
然后考虑容斥定理,dp[i]表示凑到i元的全部可能情况,答案要在dp[s]的基础上减去所有不符合要求的情况。
如果有一种硬币超出了要求,相当于他花费了d[i]+1个硬币然后再凑到s元,那么其实就是dp[s-(d[i]+1)*c[i]]
对多种硬币同时超出要求的情况dp[s-(d[i]+1)*c[i]-(d[j]+1)*c[i]...]
这几种情况是有重复的,满足容斥原理,利用二进制的方法辅助计算。代码如下:
signed main(){
ios;fre();
dp[0]=1;
cin>>c[1]>>c[2]>>c[3]>>c[4]>>n;
for(int i=1;i<=4;i++){
for(int j=c[i];j<=1e5;j++){
dp[j]+=dp[j-c[i]];
}
}
while(n--){
cin>>d[1]>>d[2]>>d[3]>>d[4]>>s;
ll ans=0;
for(int i=0;i<16;i++){
int cnt=0;ll now=0;
for(int j=1;j<=4;j++){
if(i&(1<<(j-1))) now+=(d[j]+1)*c[j],cnt++;
}
if(s-now>=0) ans+=(cnt%2*2-1)*dp[s-now];
}
cout<<-ans<<endl;
}
return 0;
}

浙公网安备 33010602011771号