这一道题的数据很明显弱了
如果题目使用容斥原理做,那么判断 总容量-用超某种硬币的量 > 0时可以AC 但是应该判断 >= 0
正确的代码:
#include "bits/stdc++.h"
using namespace std;
#define int long long
const int N = 1e5 + 5, M = 5;
int c[M], f[N], tmp[N];//f[i] -> 容量为i的方案数量
//int cnttt = 0;
//int foo()
//{
// cout << " " << cnttt ++ << endl;
// return 0;
//}
signed main()
{
int n;
cin >> c[1] >> c[2] >> c[3] >> c[4] >> n;
f[0] = 1;
for (int i = 1; i <= 4; ++i)
for (int j = c[i]; j <= 1e5; j += 1)
f[j] += f[j - c[i]];
// cout << f[10] << endl;
// + foo() +
while (n --)
{
int cnt[M], s;
cin >> cnt[1] >> cnt[2] >> cnt[3] >> cnt[4] >> s;
int res = f[s], x[5] = {0, ((cnt[1] + 1)* c[1]), ((cnt[2] + 1)* c[2]), ((cnt[3] + 1)* c[3]), ((cnt[4] + 1)* c[4])};
res -= s - x[1] >= 0 ? f[s - x[1]] : 0;
res -= s - x[2] >= 0 ? f[s - x[2]] : 0;
res -= s - x[3] >= 0 ? f[s - x[3]] : 0;
res -= s - x[4] >= 0 ? f[s - x[4]] : 0;
res += s - (x[1] + x[2]) >= 0 ? f[s - (x[1] + x[2])] : 0;
res += s - (x[1] + x[3]) >= 0 ? f[s - (x[1] + x[3])] : 0;
res += s - (x[1] + x[4]) >= 0 ? f[s - (x[1] + x[4])] : 0;
res += s - (x[2] + x[3]) >= 0 ? f[s - (x[2] + x[3])] : 0;
res += s - (x[2] + x[4]) >= 0 ? f[s - (x[2] + x[4])] : 0;
res += s - (x[3] + x[4]) >= 0 ? f[s - (x[3] + x[4])] : 0;
res -= s - (x[1] + x[2] + x[3]) >= 0 ? f[s - (x[1] + x[2] + x[3])] : 0;
res -= s - (x[1] + x[2] + x[4]) >= 0 ? f[s - (x[1] + x[2] + x[4])] : 0;
res -= s - (x[1] + x[4] + x[3]) >= 0 ? f[s - (x[1] + x[4] + x[3])] : 0;
res -= s - (x[4] + x[2] + x[3]) >= 0 ? f[s - (x[4] + x[2] + x[3])] : 0;
res += s - (x[1] + x[2] + x[3] + x[4]) >= 0 ? f[s - (x[1] + x[2] + x[3] + x[4])] : 0;
cout << res << endl;
}
return 0;
}
不严谨代码(但是能AC)
#include "bits/stdc++.h"
using namespace std;
#define int long long
const int N = 1e5 + 5, M = 5;
int c[M], f[N], tmp[N];//f[i] -> 容量为i的方案数量
//int cnttt = 0;
//int foo()
//{
// cout << " " << cnttt ++ << endl;
// return 0;
//}
signed main()
{
int n;
cin >> c[1] >> c[2] >> c[3] >> c[4] >> n;
f[0] = 1;
for (int i = 1; i <= 4; ++i)
for (int j = c[i]; j <= 1e5; j += 1)
f[j] += f[j - c[i]];
// cout << f[10] << endl;
// + foo() +
while (n --)
{
int cnt[M], s;
cin >> cnt[1] >> cnt[2] >> cnt[3] >> cnt[4] >> s;
int res = f[s], x[5] = {0, ((cnt[1] + 1)* c[1]), ((cnt[2] + 1)* c[2]), ((cnt[3] + 1)* c[3]), ((cnt[4] + 1)* c[4])};
res -= s - x[1] > 0 ? f[s - x[1]] : 0;
res -= s - x[2] > 0 ? f[s - x[2]] : 0;
res -= s - x[3] > 0 ? f[s - x[3]] : 0;
res -= s - x[4] > 0 ? f[s - x[4]] : 0;
res += s - (x[1] + x[2]) > 0 ? f[s - (x[1] + x[2])] : 0;
res += s - (x[1] + x[3]) > 0 ? f[s - (x[1] + x[3])] : 0;
res += s - (x[1] + x[4]) > 0 ? f[s - (x[1] + x[4])] : 0;
res += s - (x[2] + x[3]) > 0 ? f[s - (x[2] + x[3])] : 0;
res += s - (x[2] + x[4]) > 0 ? f[s - (x[2] + x[4])] : 0;
res += s - (x[3] + x[4]) > 0 ? f[s - (x[3] + x[4])] : 0;
res -= s - (x[1] + x[2] + x[3]) > 0 ? f[s - (x[1] + x[2] + x[3])] : 0;
res -= s - (x[1] + x[2] + x[4]) > 0 ? f[s - (x[1] + x[2] + x[4])] : 0;
res -= s - (x[1] + x[4] + x[3]) > 0 ? f[s - (x[1] + x[4] + x[3])] : 0;
res -= s - (x[4] + x[2] + x[3]) > 0 ? f[s - (x[4] + x[2] + x[3])] : 0;
res += s - (x[1] + x[2] + x[3] + x[4]) > 0 ? f[s - (x[1] + x[2] + x[3] + x[4])] : 0;
cout << res << endl;
}
return 0;
}