解析

呜呜呜不废啊
我只会跑n遍多重背包
感觉非常神仙的一道题
之所以只是蓝的可能是因为代码实现难度太低了吧
但感觉思想真的很难想到
也可能是我太菜了
容斥相关还是需要加强啊qwq

考虑如果没有硬币个数的限制的情况
显然就是个简单的完全背包了
然而如今有了硬币个数的限制
所以我们要考虑容斥

利用总方案数-硬币个数超过限制的方案数求出答案

前面的总方案数就是完全背包的dp值,关键就是对后面硬币个数超过限制方案数的求解

考虑第iii种硬币超过限制,那么就至少要使用(di+1)(d_i+1)(di​+1)个,剩下可以自由选的价值是s−ci∗(di+1)s-c_i*(d_i+1)s−ci​∗(di​+1)
那么对应的方案数就是dps−ci∗(d[i]+1)dp_{s-c_i*(d[i]+1)}dps−ci​∗(d[i]+1)​

但是这样会算重丫
比如某种方案可能会同时超过两种限制,被减了两次
因此我们就开始容斥的常用套路,再加上超过两种限制的,再减去超过三种限制的,再加回来四种限制都超过的

问题得以解决

代码

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define debug(a,b) fprintf(stderr,a,b)
const int N=3e5+100;
const double eps=1e-9;
inline ll read() {ll x=0,f=1;char c=getchar();while(!isdigit(c)) {if(c=='-') f=-1;c=getchar();}while(isdigit(c)) {x=(x<<1)+(x<<3)+c-'0';c=getchar();}return x*f;
}int n;
ll c[5],d[5],s;
ll dp[N],o=100000;
inline int calc(int x){int res(0);while(x){res+=x&1;x>>=1;}return res;
}
int mi[6];
int main() {#ifndef ONLINE_JUDGE//freopen("a.in","r",stdin);//freopen("a.out","w",stdout);
#endiffor(int i=1;i<=4;i++) c[i]=read();n=read();mi[0]=1;for(int i=1;i<=4;i++) mi[i]=mi[i-1]<<1;dp[0]=1;for(int k=1;k<=4;k++){int w=c[k];for(int i=w;i<=o;i++) dp[i]+=dp[i-w];}//for(int i=0;i<=10;i++) printf("%lld ",dp[i]);putchar('\n');while(n--){for(int i=1;i<=4;i++) d[i]=read();s=read();ll ans=0;for(int i=0;i<16;i++){int cnt=calc(i);ll tot=s;for(int k=1;k<=4;k++){if(i&mi[k-1]) tot-=c[k]*(d[k]+1);}if(tot<0) continue;ans+=pow(-1,cnt)*dp[tot];//printf("\ni=%d cnt=%d tot=%lld ans=%lld\n",i,cnt,tot,ans);}printf("%lld\n",ans);}return 0;
}
/*
1 2 5 10 1
3 2 3 1 10
*/

洛谷P1450:硬币购物(背包、容斥)相关推荐

  1. 洛谷P3349:小星星(容斥dp)

    解析 先安利一波洛谷上我介绍如何用暴力日过去的博客 现在开始务正业 考虑把dp记录状态的一维s去掉 这样单次转移复杂度变成n3n^3n3 但是这样显然会算多啊! 因为一个编号可能会用很多次 考虑容斥 ...

  2. 洛谷 洛谷 P2708 硬币翻转(高端算法)

    //DAY3.B //题源:洛谷 P2708 硬币翻转 //原题链接:https://www.luogu.com.cn/problem/P2708 #include<stdio.h> #i ...

  3. 洛谷 P2001 硬币的面值 题解

    原题链接 P2001 硬币的面值 - 洛谷 | 计算机科学教育新生态 题目描述 小A有 n n n 枚硬币,现在要买一样不超过 m m m 元的商品,他不想得到找钱(多脏啊),同时又不想带太多的硬币, ...

  4. 洛谷(P1658 购物 C++)

    题目描述: 你就要去购物了,现在你手上有 N种不同面值的硬币,每种硬币有无限多个.为了方便购物,你希望带尽量少的硬币,但要能组合出 1到 X 之间的任意值. 输入格式: 第一行两个数 X, N,以下  ...

  5. 洛谷——3399 丝绸之路(背包)

    题目背景 张骞于公元前138年曾历尽艰险出使过西域.加强了汉朝与西域各国的友好往来.从那以后,一队队骆驼商队在这漫长的商贸大道上行进,他们越过崇山峻岭,将中国的先进技术带向中亚.西亚和欧洲,将那里的香 ...

  6. 洛谷——P2708 硬币翻转

    https://www.luogu.org/problem/show?pid=2708#sub 题目背景 难度系数:☆☆☆☆☆(如果你看懂了) 题目描述 从前有很多个硬币摆在一行,有正面朝上的,也有背 ...

  7. 洛谷 1858 多人背包

    https://www.luogu.org/problem/show?pid=1858 题目描述 DD 和好朋友们要去爬山啦!他们一共有 K 个人,每个人都会背一个包.这些包的容量是相同的,都是 V. ...

  8. 洛谷P1169 树上分组背包

    题解 第一次写树上分组背包的题目. 什么是分组背包? 分组背包就是将物品进行分组每组内部只能选择一类物品. for(int i = 1;i <= N;++i){for(int j = 0;j & ...

  9. 洛谷 [P2964] 硬币的游戏

    博弈论+dp 依旧是博弈论的壳子,但问的是最大值,所以要dp 设 dp[i][j] 表示该取 i 号硬币,上一次取了 j 个的先手能取的最大值, 因为每次从小到大枚举复杂度太高,所以我们要从 dp[i ...

最新文章

  1. 【Android游戏开发之十】(优化处理)详细剖析Android Traceview 效率检视工具
  2. 新闻频道管理的炫酷实现
  3. 普罗米修斯监控系统_基于Prometheus和Grafana的监控平台 - 环境搭建
  4. Codeforces Round #665 (Div. 2)
  5. ASP.NET MVC的路由
  6. Mybatis 拦截器介绍
  7. 博客地址 RSS地址
  8. Android官方开发文档Training系列课程中文版:后台服务之IntentService的创建
  9. 二进制指数类型退避算法
  10. repo init 是啥意思
  11. jquery中的trigger()和preventDefault()方法
  12. java比较两个对象_Java比较两个对象
  13. Java_写出java MyJava abc cde efg 运行的结果(向main()方法中传参)
  14. Jenkins下载安装
  15. linux 目录配额,详细讲解linux磁盘配额之Quota命令
  16. 处理Nginx返回octet-stream数据流的配置
  17. SpringBoot安全登录验证
  18. 唐迟长难句逻辑思维导图(含英语高分笔记)
  19. Liunx-centos8入门+配置网络
  20. i5 6600 HD530联想扬天S5250黑苹果

热门文章

  1. 如何快速解剖数据背后隐藏的信息
  2. 《自然》杂志:中国人越来越沉迷于对着一个叫“区块链”的东西胡言乱语
  3. 数据挖掘在呼叫中心的六大应用点
  4. 头文件定义全局变量_5.2 C++局部变量与全局变量 | 输出局部全局变量
  5. 针对Spring的Spring Retry 我发现了这样一个大家都不知道的技巧!
  6. java 生成jar_java如何生成jar
  7. mysql修改字段的顺序_Mysql中如何修改字段的排列顺序?
  8. # 睡眠3秒_【for fun】睡眠排序算法
  9. C# Task 循环任务_C# Task.Run调用外部参数
  10. dataset的去重计数 g2_ExcelExcel去重、计数一步到位,这个方法简单到哭