题目传送门

题目大意

给出 \(n\),第 \(i\) 个数有 \(i\) 个,问凑出 \(n\) 的方案数。

\(n\le 10^5\)

思路

呜呜呜,傻掉了。。。

首先想到根号分治,分别考虑 \([1,\sqrt n]\) 以及 \([\sqrt n+1,n]\)。

  1. \([1,\sqrt n]\)

不难看出这部分可以直接 dp,设 \(f_{i,j}\) 为前面 \(i\) 种物品选出重量为 \(j\) 的方案数,可以得到转移式:

\[f_{i,j}=f_{i-1,j}+f_{i,j-i}-f_{i-1,j-i\times (i+1)}
\]
  1. \([\sqrt n+1,n]\)

不难看出这部分最多选出 \(\sqrt n\) 个物品,于是可以设 \(g_{i,j}\) 表示选了 \(i\) 物品,选出重量为 \(j\) 的方案数。可以得到转移式:

\[g_{i,j}=g_{i,j-i}+g_{i,j-\sqrt n-1}
\]

具体含义就是转移有两种,第一种就是集体右移,即重量为 \(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 有限背包计数问题的更多相关文章

  1. 51nod 1597 有限背包计数问题 (背包 分块)

    题意 题目链接 Sol 不会做啊AAA.. 暴力上肯定是不行的,考虑根号分组 设\(m = \sqrt{n}\) 对于前\(m\)个直接暴力,利用单调队列优化多重背包的思想,按\(\% i\)分组一下 ...

  2. 51Nod 有限背包计数问题 题解报告

    首先这道题理论上是可以做到O(nlogn)的,因为OEIS上有一个明显可以用多项式乘法加速的式子 但是由于模数不是很兹磁,所以导致nlogn很难写 在这里说一下O(n*sqrt(n))的做法 首先我们 ...

  3. 51Nod1957 有限背包计数问题

    传送门 另一个传送门 这题还挺有意思…… 先贴一波出题人的题解…… (啥你说你看不见?看来你还没过啊,等着A了再看或者乖乖花点头盾好了……) 然后是我的做法……思想都是一样的,只是细节不一样而已…… ...

  4. [51nod1597]有限背包计数问题

    你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少 两种方案不同当且仅当存在至少一个数i满足第i种物品使用的数量不同 Input 第一行一个正整数n 1 ...

  5. 2018.09.25 51nod1597 有限背包计数问题(背包+前缀和优化)

    传送门 dp好题. 我认为原题的描述已经很清楚了: 你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少. 两种方案不同当且仅当存在至少一个数i满足第i种 ...

  6. 【LOJ6089】小Y的背包计数问题(动态规划)

    [LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...

  7. LOJ #6089. 小 Y 的背包计数问题

    LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...

  8. LOJ#6089 小 Y 的背包计数问题 - DP精题

    题面 题解 (本篇文章深度剖析,若想尽快做出题的看官可以参考知名博主某C202044zxy的这篇题解:https://blog.csdn.net/C202044zxy/article/details/ ...

  9. LOJ6089 小Y的背包计数问题(根号优化背包)

    Solutioon 这道题利用根号分治可以把复杂度降到n根号n级别. 我们发现当物品体积大与根号n时,就是一个完全背包,换句话说就是没有了个数限制. 进一步我们发现,这个背包最多只能放根号n个物品. ...

随机推荐

  1. 安装或更新时,pip出错,“No module named ‘pip’”

    解决办法: 在pycharm终端(Terminal)中 首先执行 :python -m ensurepip 然后执行 :python -m pip install --upgrade pip

  2. 关于electron-vue打包后静态视频文件无法正常加载的问题解决方法

    最近在使用electron-builder构建vue项目的时候发现在生产模式下视频可以正常加载并显示,但是一旦打包到开发环境下,视频就读取不出来了,控制台也并没有报错 一开始博主以为是路径问题,在将路 ...

  3. Linux制作根文件系统笔记

    测试平台 宿主机平台:Ubuntu 12.04.4 LTS 目标机:Easy-ARM IMX283 目标机内核:Linux 2.6.35.3 交叉编译器:arm-linux-gcc 4.4.4 Bus ...

  4. 第09课:GDB 实用调试技巧(下)

    本节课的核心内容: 多线程下禁止线程切换 条件断点 使用 GDB 调试多进程程序 多线程下禁止线程切换 假设现在有 5 个线程,除了主线程,工作线程都是下面这样的一个函数: void thread_p ...

  5. BeanFactory和ApplicationContext对比

    一.BeanFactory和ApplicationContext对比 其中,ApplicationContext容器即时加载,就是一加载配置文件,就会创建对象,且自动装配bean(即写道xml中bea ...

  6. java.net.NoRouteToHostException: Cannot assign requested address

    今天压力测试时, 刚开始出现了很多异常, 都是 java.net.NoRouteToHostException: Cannot assign requested address.  经网上查资料, 是 ...

  7. 10.6Java学习

    1.类,对象,方法的定义.2.标识符分为两类:关键字/常见的基本类型:boolean(布尔型),byte(字节型),char(字符型),double(双精度),float(浮点),int(整型),lo ...

  8. 最新版微软视窗(Windows)作业系统下载(2020-08-19)

    为了更好的使用WSL(Windows Subsystem For Linux),不得不用最新的windows 10 2004版了,这个版本的WSL已经是第二版了,即WSL2.下面给出下载地址 系统发布 ...

  9. 关于buildroot移植的思考

    buildroot是一个成熟的SDK框架,基于它有了openwrt. 曾经有一个项目,需要将原有的OpenWrt SDK改造,并且将软件框架重新定义.尝试精简原来的OpenWrt,并且删除所有的软件包 ...

  10. PHP中的IMAP扩展简单入门

    对于邮件处理来说,大家比较熟悉的应该是 POP3 . SMTP 这类的协议,而今天我们介绍的 IMAP 其实也是非常常用的一种邮件处理协议.它和 POP3 比较类似,都是以接收处理邮件为主.不过相对于 ...