题目传送门

题目大意

给出 \(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. 源码解析.Net中DependencyInjection的实现

    前言 笔者的这篇文章和上篇文章思路一样,不注重依赖注入的使用方法,更加注重源码的实现,我尽量的表达清楚内容,让读者能够真正的学到东西.如果有不太清楚依赖注入是什么或怎么在.Net项目中使用的话,请点击 ...

  2. 检测一个页面所用的时间的js

    window.onload = function () { var loadTime = window.performance.timing.domContentLoadedEventEnd-wind ...

  3. kratos

    技术文章 日志库的使用姿势 通过 layout 探索 kratos 运行原理 发版日志 发布日志 - kratos v2.0.5 版本发布 发布日志 - kratos v2.0.4 版本发布

  4. AWS EC2 实例 SSH 无法登录故障

    文章链接 故障表现 在使用 jumperver 登录 AWS ec2 实例的时候发现 ssh 配合秘钥登录的时候无法登录, 具体报错如下: ssh -i /path/xx.pem user@10.0. ...

  5. C# Dapper基本三层架构使用 (一、架构关系)

    Dapper是一款轻量级ORM工具.如果你在小的项目中,使用Entity Framework.NHibernate 来处理大数据访问及关系映射,未免有点杀鸡用牛刀.你又觉得ORM省时省力,这时Dapp ...

  6. javassist 使用笔记

    javassist Javassist 是一个开源的分析.编辑和创建Java字节码的类库.其主要的优点,在于简单,而且快速.直接使用 java 编码的形式,而不需要了解虚拟机指令,就能动态改变类的结构 ...

  7. Git 初识和使用

    目录 目录 目录 概念 工作区/暂存区/版本库 master 版本号 常见命令 环境搭建 Linux 下 Git 和 GitHub 环境的搭建 Git 本地操作 本地仓库的创建和使用 查看信息 查看状 ...

  8. 九、Abp vNext 基础篇丨评论聚合功能

    介绍 评论本来是要放到标签里面去讲的,但是因为上一章东西有点多了,我就没放进去,这一章单独拿出来,内容不多大家自己写写就可以,也算是对前面讲解的一个小练习吧. 相关注释我也加在代码上面了,大家看看代码 ...

  9. spark相关介绍-提取hive表(一)

    本文环境说明 centos服务器 jupyter的scala核spylon-kernel spark-2.4.0 scala-2.11.12 hadoop-2.6.0 本文主要内容 spark读取hi ...

  10. POJ1741——Tree(树的点分治)

    1 /* *********************************************** 2 Author :kuangbin 3 Created Time :2013-11-17 1 ...