题意:链接
方法:容斥原理
解析:简单题,不掉坑都对不起我自己
这题很好想的一个容斥原理,因为一共只有四种硬币,我们不方便计算满足题中要求的方案数,但是从反向思考,我们需要做的就是减掉奇数个硬币用超额的情况,然后加上偶数个硬币用超额的情况就是最终的答案(当然状态是0000的时候看做是一个基准)。
然后我没什么说的了,只是有一些细节需要注意下:
1.要用long long
2.完全背包千万不要傻到每次重新背,直接一次预处理就好,不过我为什么要重新背啊!(差了8s)
代码:
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 100010
using namespace std;
typedef long long ll;
int c[5],tot;
int d[5],s;
ll f[N];
void backpack(int w)
{
memset(f,0,sizeof(f));
f[0]=1;
for(int i=1;i<=4;i++)
{
for(int j=c[i];j<=w;j++)
{
f[j]+=f[j-c[i]];
}
}
}
ll solve()
{
ll ans=0;
for(int i=0;i<(1<<4);i++)
{
int tmp=s,flag=0;
for(int j=1;j<=4;j++)
{
if(i&(1<<(j-1)))tmp-=(d[j]+1)*c[j],flag^=1;
}
if(tmp<0)continue;
backpack(tmp);
if(flag)ans-=f[tmp];
else ans+=f[tmp];
}
return ans;
}
int main()
{
scanf("%d%d%d%d%d",&c[1],&c[2],&c[3],&c[4],&tot);
while(tot--)
{
scanf("%d%d%d%d%d",&d[1],&d[2],&d[3],&d[4],&s);
ll print=solve();
if(print<0)printf("0\n");
else printf("%lld\n",print);
}
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-12-28 01:15:25