题解 51nod 1597 有限背包计数问题
题目大意
给出 \(n\),第 \(i\) 个数有 \(i\) 个,问凑出 \(n\) 的方案数。
\(n\le 10^5\)
思路
呜呜呜,傻掉了。。。
首先想到根号分治,分别考虑 \([1,\sqrt n]\) 以及 \([\sqrt n+1,n]\)。
- \([1,\sqrt n]\)
不难看出这部分可以直接 dp,设 \(f_{i,j}\) 为前面 \(i\) 种物品选出重量为 \(j\) 的方案数,可以得到转移式:
\]
- \([\sqrt n+1,n]\)
不难看出这部分最多选出 \(\sqrt n\) 个物品,于是可以设 \(g_{i,j}\) 表示选了 \(i\) 个 物品,选出重量为 \(j\) 的方案数。可以得到转移式:
\]
具体含义就是转移有两种,第一种就是集体右移,即重量为 \(k\) 的都变为 \(k+1\),另外一种就是选 \(\sqrt n+1\)。
综上时空复杂度 \(\Theta(n\log n)\),第一种记得滚动数组,不然会 MLE。
\(\texttt{Code}\)
#include <bits/stdc++.h>
using namespace std;
#define Int register int
#define mod 23333333
#define MAXN 100005
#define MAXM 325
template <typename T> void read (T &x){char c = getchar ();x = 0;int f = 1;while (c < '0' || c > '9') f = (c == '-' ? -1 : 1),c = getchar ();while (c >= '0' && c <= '9') x = x * 10 + c - '0',c = getchar ();x *= f;}
template <typename T,typename ... Args> void read (T &x,Args& ... args){read (x),read (args...);}
template <typename T> void write (T x){if (x < 0) x = -x,putchar ('-');if (x > 9) write (x / 10);putchar (x % 10 + '0');}
int n,sqr;
int f[2][MAXN],g[MAXM][MAXN],f1[MAXN],f2[MAXN];
/*
f[i][j] 表示前面i个物品选出重量j的方案数,g[i][j]表示i个物品选出重量j的方案数
f[i][j]=f[i-1][j]+f[i][j-i]-f[i-1][j-i*(i+1)]
g[i][j]=g[i][j-i]+g[i-1][j-sqr-1]
*/
int dec (int a,int b){return a >= b ? a - b : a + mod - b;}
int add (int a,int b){return a + b >= mod ? a + b - mod : a + b;}
void Work1 (){
f[0][0] = 1;
for (Int i = 1;i <= sqr;++ i)
for (Int j = 0;j <= n;++ j)
f[i & 1][j] = add (f[i - 1 & 1][j],dec (j >= i ? f[i & 1][j - i] : 0,j >= i * (i + 1) ? f[i - 1 & 1][j - i * (i + 1)] : 0));
for (Int i = 0;i <= n;++ i) f1[i] = f[sqr & 1][i];
}
void Work2 (){
g[0][0] = 1;
for (Int i = 1;i <= sqr;++ i)
for (Int j = 0;j <= n;++ j)
g[i][j] = add (j >= i ? g[i][j - i] : 0,j >= sqr + 1 ? g[i - 1][j - sqr - 1] : 0);
for (Int i = 0;i <= n;++ i)
for (Int j = 0;j <= sqr;++ j) f2[i] = add (f2[i],g[j][i]);
}
signed main(){
read (n),sqr = sqrt (n),Work1(),Work2 ();
int ans = 0;for (Int i = 0;i <= n;++ i) ans = add (ans,1ll * f1[i] * f2[n - i] % mod);
write (ans),putchar ('\n');
return 0;
}
题解 51nod 1597 有限背包计数问题的更多相关文章
- 51nod 1597 有限背包计数问题 (背包 分块)
题意 题目链接 Sol 不会做啊AAA.. 暴力上肯定是不行的,考虑根号分组 设\(m = \sqrt{n}\) 对于前\(m\)个直接暴力,利用单调队列优化多重背包的思想,按\(\% i\)分组一下 ...
- 51Nod 有限背包计数问题 题解报告
首先这道题理论上是可以做到O(nlogn)的,因为OEIS上有一个明显可以用多项式乘法加速的式子 但是由于模数不是很兹磁,所以导致nlogn很难写 在这里说一下O(n*sqrt(n))的做法 首先我们 ...
- 51Nod1957 有限背包计数问题
传送门 另一个传送门 这题还挺有意思…… 先贴一波出题人的题解…… (啥你说你看不见?看来你还没过啊,等着A了再看或者乖乖花点头盾好了……) 然后是我的做法……思想都是一样的,只是细节不一样而已…… ...
- [51nod1597]有限背包计数问题
你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少 两种方案不同当且仅当存在至少一个数i满足第i种物品使用的数量不同 Input 第一行一个正整数n 1 ...
- 2018.09.25 51nod1597 有限背包计数问题(背包+前缀和优化)
传送门 dp好题. 我认为原题的描述已经很清楚了: 你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少. 两种方案不同当且仅当存在至少一个数i满足第i种 ...
- 【LOJ6089】小Y的背包计数问题(动态规划)
[LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...
- LOJ #6089. 小 Y 的背包计数问题
LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...
- LOJ#6089 小 Y 的背包计数问题 - DP精题
题面 题解 (本篇文章深度剖析,若想尽快做出题的看官可以参考知名博主某C202044zxy的这篇题解:https://blog.csdn.net/C202044zxy/article/details/ ...
- LOJ6089 小Y的背包计数问题(根号优化背包)
Solutioon 这道题利用根号分治可以把复杂度降到n根号n级别. 我们发现当物品体积大与根号n时,就是一个完全背包,换句话说就是没有了个数限制. 进一步我们发现,这个背包最多只能放根号n个物品. ...
随机推荐
- 第13篇-通过InterpreterCodelet存储机器指令片段
在TemplateInterpreterGenerator::generate_all()函数中生成了许多字节码指令以及一些虚拟机辅助执行的机器指令片段,例如生成空指针异常抛出入口的实现如下: { C ...
- apt-get 安装程序时报 'E: Unable to locate package xxx' 错误处理办法
提示无法定位包,要执行命令更新: sudo apt-get update
- T-SQL - query01_创建数据库|创建表|添加数据|简单查询
时间:2017-09-29 整理:byzqy 本篇以"梁山好汉花名册"为例,记录MS SQLServer T-SQL语句的使用,包含命令: 创建数据库 | 删除数据库 创建表 | ...
- Linux复习笔记-001-进程的管理
1.什么是进程? 进程是已经启动的可执行的程序运行实例. 程序是二进制文件,静态 ./bin/date/ /usr/sbin/ 进程:是程序运行的过程 2.Linux为1的进程? centos5或6为 ...
- JVM详解(一)——概述
Test https://www.cnblogs.com/yrxing/p/14651346.html#gc的基础知识 https://www.cnblogs.com/yinzhengjie/p/92 ...
- Gram-Schmidt图像融合
遥感图像融合的定义是通过将多光谱低分辨率的图像和高分辨率的全色波段进行融合从而得到信息量更丰富的遥感图像.常用的遥感图像融合方法有Brovey\PCA\Gram-Schmidt方法.其中Gram-Sc ...
- 多文件Makefile编写
工作过程中,平时不怎么关注Makefile的书写规则,对于遇到的编译错误一般能看懂Makefile的基本规则也能解决.但如果想要编写Makefile文件还是有相当的难度的,更不用说包含多个目录和文件的 ...
- 如何在云效流水线 Flow中构建属于自己的NPM仓库
如何在云效流水线 Flow中构建属于自己的NPM仓库,Flow 通过各种构建组件,对各种语言提供了制品打包能力,让用户可以快速的使用流水线构建制品,并通过后续的部署任务进行部署.Flow 已经完成了与 ...
- Redis——set,hash与列表
一.List列表 基于Linked List实现 元素是字符串类型 列表头尾增删快,中间增删慢,增删元素是常态 元素可以重复出现 最多包含2^32-1元素 列表的索引 从左至右,从0开始 从右至左,从 ...
- bash-completion linux命令补全
1.有时候用docker run 或者kubectl 想tab补全的时候用不了 这个时候可以安装一个神奇的包bash-completion yum install bash-completion 2. ...