[lnsyoj729/luoguP1450/HAOI2008]硬币购物
题意
给出一个长度为 的序列 ,给出 个询问,每个询问给出一个长度为 的序列 和 整数 ,要求构造出长度为 的序列 ,使得 ,且 ,求 的方案数
sol
一眼多重背包问题,但无论使用哪种做法都无法在 内解决,只好思考容斥。
(注:接下来,我们记 表示满足 的方案数)
答案显然不是 ,因为存在序列 限制。考虑减掉对于 中的每个数 ,当 时的方案数,即 (因为需要保证 ,因此先选出 个 ,再正常选择)。
此时多减了两个数多选的情况,由此,即可写出容斥式
数组也很好计算,事实上,它就是完全背包一维优化的 数组。
代码
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int N = 100005;
int c[4], d[4];
int n, s;
long long f[N];
int p(int x){
return 1 - x % 2 * 2;
}
void init(){
f[0] = 1;
for (int i = 0; i < 4; i ++ )
for (int j = c[i]; j <= 100000; j ++ )
f[j] += f[j - c[i]];
}
int main(){
scanf("%d%d%d%d%d", &c[0], &c[1], &c[2], &c[3], &n);
init();
while (n -- ){
scanf("%d%d%d%d%d", &d[0], &d[1], &d[2], &d[3], &s);
long long ans = 0;
for (int s0 = 0; s0 < 16; s0 ++ ){
int l = 0;
long long sum = 0;
for (int u = 0; u < 4; u ++ )
if ((s0 >> u) & 1) l ++ , sum += (long long) c[u] * (d[u] + 1);
if (s >= sum) ans += p(l) * f[s - sum];
}
printf("%lld\n", ans);
}
}
蒟蒻犯的若至错误
- init() 和 main() 中的下标起始位置不统一
分类:
题解 / 2024训练
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 使用C#创建一个MCP客户端
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现