完全背包加上容斥,思想非常妙
#include <bits/stdc++.h>
#define for1(i,a,b) for (int i = a;i <= b;i ++)
#define ll long long
const int maxn = 1e5+5;
const int inf = 99824353;
long long dp[maxn+10];
int c[10],d[10],T;
int sum;
ll ans;
int main()
{
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
for1(i,1,4)
std::cin>>c[i];
dp[0] = 1;//0的方案数:不取
for1(i,1,4)//完全背包
for1(j,c[i],maxn)
dp[j] += dp[j-c[i]];
std::cin>>T;
while (T--)
{
ans = 0;
for1(i,1,4)
std::cin>> d[i];
std::cin>>sum;
for1(i,0,15)//容斥
{
ll ji = sum;
int cnt = 0;
for1(j,1,4)
if ((i>>(j - 1)) & 1)
{
ji -= c[j] * (d[j] + 1);
cnt^=1;
}
if (ji < 0) continue;
if (!cnt) //单数个就加,双数个就减
ans += dp[ji];
else
ans -= dp[ji];
}
std::cout<<ans<<'\n';
}
return 0;
}
标签:std,cnt,P1450,硬币,ji,ans,for1,dp,HAOI2008
From: https://www.cnblogs.com/yyx525jia/p/17128361.html