题解 \(by\;zj\varphi\)

一道 \(\rm dp\) 题。

现将所有种类从小到大排序,然后判断,若最小的已经大于了 \(\rm l\),那么直接就是一个裸的完全背包,因为选的总数量有限制。

设 \(\rm f_{i,j,k}\) 为选了前 \(\rm i\) 种物品,总数为 \(\rm j\),容量为 \(\rm k\),是否可行,转移很简单。

对于另一种情况,能构造出的最小差距就是 \(v_1\),那么只要记录一下模 \(\rm v_1\) 的值即可。

设 \(\rm f_{i,j}\) 为选了 \(\rm i\) 个有限制的物品,模数为 \(j\) 的状态下最小和为多少,则有转移方程:

\[\rm f_{i,j}=\min(f_{i,j},f_{i,(j-v_i)mod\;v_1}+v_i)\;\; v_i<l\\
f_{i,j}=\min(f_{i,j},f_{i-1,(j-v_i)mod\;v_1}+v_i)\;\; v_i\ge l
\]

发现这个转移会出现环,所以直接最短路。

#include<bits/stdc++.h>
#define ri register signed
#define p(i) ++i
namespace IO{
char buf[1<<21],*p1=buf,*p2=buf;
#define gc() p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?(-1):*p1++
struct nanfeng_stream{
template<typename T>inline nanfeng_stream &operator>>(T &x) {
ri f=0;x=0;register char ch=gc();
while(!isdigit(ch)) {f|=ch=='-';ch=gc();}
while(isdigit(ch)) {x=(x<<1)+(x<<3)+(ch^48);ch=gc();}
return x=f?-x:x,*this;
}
}cin;
}
using IO::cin;
namespace nanfeng{
#define node(nm,v,dis) (node){nm,v,dis}
#define FI FILE *IN
#define FO FILE *OUT
template<typename T>inline T cmax(T x,T y) {return x>y?x:y;}
template<typename T>inline T cmin(T x,T y) {return x>y?y:x;}
typedef long long ll;
static const int N=51,M=3e5+7,C=31,V=1e4+7;
int v[N],n,m,l,c;
bool vis[C][V];
ll dis[C][V];
struct node{int nm,v;ll dis;};
std::queue<node> que;
std::bitset<M> f[N][C];
inline void spfa() {
memset(dis,127,sizeof(dis));
dis[0][0]=0;
que.push(node(0,0,0));
while(!que.empty()) {
node nw=que.front();que.pop();
vis[nw.nm][nw.v]=0;
for (ri i(2);i<=n;p(i)) {
int tmp;
if (v[i]<l) {
if (dis[nw.nm][tmp=(nw.v+v[i])%v[1]]>nw.dis+v[i]) {
dis[nw.nm][tmp]=nw.dis+v[i];
if (!vis[nw.nm][tmp]) que.push(node(nw.nm,tmp,nw.dis+v[i])),vis[nw.nm][tmp]=1;
}
} else if (nw.nm<c) {
if (dis[nw.nm+1][tmp=(nw.v+v[i])%v[1]]>nw.dis+v[i]) {
dis[nw.nm+1][tmp]=nw.dis+v[i];
if (!vis[nw.nm+1][tmp]) que.push(node(nw.nm+1,tmp,nw.dis+v[i])),vis[nw.nm+1][tmp]=1;
}
}
}
}
}
inline int main() {
//FI=freopen("nanfeng.in","r",stdin);
//FO=freopen("nanfeng.out","w",stdout);
cin >> n >> m;
for (ri i(1);i<=n;p(i)) cin >> v[i];
cin >> l >> c;
std::sort(v+1,v+n+1);
if (v[1]>=l) {
f[0][0][0]=1;
for (ri i(1);i<=n;p(i)) {
for (ri j(0);j<=c;p(j)) {
f[i][j]=f[i-1][j];
if (j) f[i][j]|=f[i][j-1]<<v[i];
}
}
for (ri i(0);i<c;p(i)) f[n][c]|=f[n][i];
for (ri i(1);i<=m;p(i)) {
ll w;cin >> w;
if (w>=M) puts("No");
else printf("%s\n",f[n][c][w]?"Yes":"No");
}
} else if (v[1]<l) {
spfa();
for (ri i(0);i<c;p(i))
for (ri j(0);j<v[1];p(j)) dis[c][j]=cmin(dis[c][j],dis[i][j]);
for (ri i(1);i<=m;p(i)) {
ll w;cin >> w;
printf("%s\n",w>=dis[c][w%v[1]]?"Yes":"No");
}
}
return 0;
}
}
int main() {return nanfeng::main();}\

NOIP 模拟 $29\; \rm 完全背包问题$的更多相关文章

  1. NOIP 模拟 $29\; \rm 最近公共祖先$

    题解 \(by\;zj\varphi\) 首先考虑,如果将一个点修改成了黑点,那么它能够造成多少贡献. 它先会对自己的子树中的答案造成 \(w_x\) 的贡献. 考虑祖先时,它会对不包括自己的子树造成 ...

  2. NOIP 模拟 $29\; \rm 最长不下降子序列$

    题解 \(by\;zj\varphi\) 观察这个序列,发现模数很小,所以它的循环节很小. 那么可以直接在循环节上做最长上升子序列,但是循环节中的逆序对会对拼接后的答案造成影响. 没有必要找逆序对个数 ...

  3. noip模拟29[简单的板子题](虽然我不会)

    \(noip模拟29\;solutions\) 这次考试给我最大的伤害,让我意识到了差距 这场考试可以说是非常的简单,就是简单到,看两眼,打个表就有结果了 但是呢?我考得非常的完蛋,只有30pts 据 ...

  4. NOIP模拟 1

    NOIP模拟1,到现在时间已经比较长了.. 那天是6.14,今天7.18了 //然鹅我看着最前边缺失的模拟1,还是终于忍不住把它补上,为了保持顺序2345重新发布了一遍.. #   用  户  名   ...

  5. 2021.5.22 noip模拟1

    这场考试考得很烂 连暴力都没打好 只拿了25分,,,,,,,,好好总结 T1序列 A. 序列 题目描述 HZ每周一都要举行升旗仪式,国旗班会站成一整列整齐的向前行进. 郭神作为摄像师想要选取其中一段照 ...

  6. NOIP 模拟 $22\; \rm f$

    题解 \(by\;zj\varphi\) 对于一个数,如果它二进制下第 \(i\) 位为 \(1\),那么 \(\rm x\) 在这一位选 \(1\) 的贡献就是和它不同的最高为为 \(i\) 的数的 ...

  7. NOIP模拟3

    期望得分:30+90+100=220 实际得分:30+0+10=40 T1智障错误:n*m是n行m列,硬是做成了m行n列 T2智障错误:读入三个数写了两个%d T3智障错误:数值相同不代表是同一个数 ...

  8. 7.22 NOIP模拟7

    又是炸掉的一次考试 T1.方程的解 本次考试最容易骗分的一道题,但是由于T2花的时间太多,我竟然连a+b=c都没判..暴力掉了40分. 首先a+b=c,只有一组解. 然后是a=1,b=1,答案是c-1 ...

  9. NOIP模拟 29

    T1第一眼觉得是网络流 看见4e6条边200次增广我犹豫了 O(n)都过不去的赶脚.. 可是除了网络流板子我还会什么呢 于是交了个智障的EK 还是用dijkstra跑的 居然有50分!$(RP--)$ ...

随机推荐

  1. hdu 2093 成绩排名

    思路: 没啥思路,就是定义结构体,跟题目,走,当时没想到对那个括号的处理,后面看了题解,才知道用个getchar直接判断 算是一个值得思考的点. 代码: #include<bits/stdc++ ...

  2. Docker从容器拷贝文件到宿主机或从宿主机拷贝文件到容器

    1.从容器里面拷文件到宿主机? 答:在宿主机里面执行以下命令 docker cp 容器名:要拷贝的文件在容器里面的路径       要拷贝到宿主机的相应路径 示例: 假设容器名为testtomcat, ...

  3. python使用笔记23--面向对象编程

    1.面向对象编程概念 面向对象是包含面向过程 面向过程编程 买车: 1.4s看车,买车 2.上保险 保险公司 3.交税 地税局 4.交管所 上牌 面向对象编程 卖车处: 1.4s 2.保险 3.交税 ...

  4. python使用笔记006-函数+json操作

    一.函数 函数:提高代码的复用性 1.1 函数的定义 1 def hello(): 2 print('hello') 3 print('fdsfjslkfs') 4 5 #函数不调用就不会执行 6 h ...

  5. Java基础00-Debug11

    1. Debug 1.1 Debug概述 1.2 Debug操作流程 1.2.1 如何加断点 1.2.2 如何运行加了断点的程序 1.2.3 看哪里 1.2.4 点哪里 1.2.5 如何删除断点 多个 ...

  6. 程序员们,还在挣扎着上不了github吗

    前言 无兄弟,不篮球:无github,不代码.github和stackoverflow是程序员们的最爱,哪怕是github总是在抽疯,虐了程序员们千百遍,但他们还是想各种办法艰难地在github分享他 ...

  7. NestJS WebSocket 开始使用

    使用NestJs提供WebSocket服务. 本文会在新建项目的基础上增加2个类 Gateway 实现业务逻辑的地方 WebSocketAdapter WebSocket适配器 新建项目 新建一个项目 ...

  8. 每天五分钟Go - 循环语句

    带条件的for循环 for init; condition; post { } 示例代码 for i:=0;i<10;i++{ fmt.Println("current:", ...

  9. Mysql 基础用法

    #创建表 CREATE TABLE table_name (column_name int) CREATE TABLE IF NOT EXISTS `runoob_tbl`( `runoob_id` ...

  10. SSM整合文件框架

    1.项目架构如图 web3.0项目,tomcat9.0,自动生成web.xml文件 按照mybatis配置,先自动生成dao层,更改相应信息 我mybatis如何配置:   https://www.c ...