传送门

另一个传送门

这题还挺有意思……

先贴一波出题人的题解……

(啥你说你看不见?看来你还没过啊,等着A了再看或者乖乖花点头盾好了……)

然后是我的做法……思想都是一样的,只是细节不一样而已……

令$B=\lceil \sqrt{n}\rceil$,把物品分$\ge B$和$<B$两类考虑:

对于大小$<B$的物品,直接用多重背包计数的方法去做即可,令$f[i][j]$表示使用前$i$个物品凑出$j$的方案数,显然有

\begin{align}f[i][j]=\sum_{k=0}^i f[i-1][j-ki]\end{align}

直接算的话时间肯定会爆炸,所以简单变形一下,得到

$f[i][j]=f[i][j-i]+f[i-1][j]-f[i-1][i(i+1)]$

应该不难理解,就是对上一个状态的转移区间做一下微调,加上右端点并减掉左端点。

这样每个状态的计算时间就变成$O(1)$了,而总共有$O(n\sqrt{n})$个状态,因此这部分的复杂度就是$O(n\sqrt{n})$。

对于大小$\ge B$的物品,显然这些物品是用不完的,直接当作完全背包处理即可。又因为这些物品最多使用$\lfloor \frac n B\rfloor$个,因此可以令$g[i][j]$表示强制只能使用大小$\ge B$的物品时用$i$个物品凑出$j$的方案数。

直接算不太好算,我们考虑给物品动态添加大小:

$g[i][j]=g[i-1][j-B]+g[i][j-i]$

前一种是添加一个大小为$B$的物品,后一种是把所有物品的大小都$+1$,应该不难看出来这样可以做到不重不漏地统计所有方案。

使用的物品数不会超过$\sqrt{n}$,因此状态数仍然是$O(n\sqrt{n})$,单次转移$O(1)$,这样后半部分的复杂度就也是$O(n\sqrt{n})$了。

最后合并两部分的结果即可,显然有

\begin{align}Ans=\sum_{i=0}^n f[n-i]\sum_{j=0}^{\lfloor\frac n B\rfloor}g[j][n-i]\end{align}

直接算是$O(n\sqrt{n})$的,如果在算$g$的时候顺便算一下$h[j]=\sum_i g[i][j]$的话可以降到$O(n)$,再加上分块DP的复杂度,总复杂度就是$O(n\sqrt{n})$。

 #include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
const int maxn=,p=;
int n,B,f[][maxn]={{}},g[][maxn]={{}},h[maxn]={},cur=,ans=;
int main(){
scanf("%d",&n);
B=(int)ceil(sqrt(n));
f[][]=g[][]=h[]=;
for(int i=;i*B<=n;i++){
cur^=;
for(int j=(i-)*B;j<i*B;j++)g[cur][j]=;
for(int j=i*B;j<=n;j++){
g[cur][j]=g[cur^][j-B];
if(j>=i)g[cur][j]=(g[cur][j]+g[cur][j-i])%p;
h[j]=(h[j]+g[cur][j])%p;
}
}
cur=;
for(int i=;i<B;i++){
cur^=;
for(int j=;j<=n;j++){
f[cur][j]=f[cur^][j];
if(j>=i){
f[cur][j]=(f[cur][j]+f[cur][j-i])%p;
if(j>=i*(i+))f[cur][j]=(f[cur][j]-f[cur^][j-i*(i+)])%p;
}
}
}
for(int i=;i<=n;i++)ans=(ans+(int)((long long)f[cur][i]*h[n-i]%p))%p;
if(ans<)ans+=p;
printf("%d",ans);
return ;
}

话说听说这题有多项式乘法加速的$O(n\log n)$做法,然而翻了翻51Nod的排行榜并没有看到写这种做法的……看了半天OEIS也没看懂怎么用多项式乘法加速,算了反正分块跑得也挺快我就用分块算了……

51Nod1957 有限背包计数问题的更多相关文章

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

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

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

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

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

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

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

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

  5. 题解 51nod 1597 有限背包计数问题

    题目传送门 题目大意 给出 \(n\),第 \(i\) 个数有 \(i\) 个,问凑出 \(n\) 的方案数. \(n\le 10^5\) 思路 呜呜呜,傻掉了... 首先想到根号分治,分别考虑 \( ...

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

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

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

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

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

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

  9. LOJ6089 小Y的背包计数问题 背包、根号分治

    题目传送门 题意:给出$N$表示背包容量,且会给出$N$种物品,第$i$个物品大小为$i$,数量也为$i$,求装满这个背包的方案数,对$23333333$取模.$N \leq 10^5$ $23333 ...

随机推荐

  1. 可持久化数据结构QwQ(持续更新中)

    可持久化留下的迹象 我们俯身欣赏 ——<膜你抄>By Menci&24OI Micardi最近在学可持久化的东西,可持久化线段树.可持久化并查集.可持久化01Trie......等 ...

  2. React第二篇:组件的生命周期

    前言:因为生命周期是必须要掌握的,所以React的第二篇咱就写这. (版本:16.3.2) React的生命周期大致分为四个状态:分别是Mouting.Updating.Unmounting.Erro ...

  3. Drupal Coder 模块远程命令执行分析(SA-CONTRIB-2016-039)

    转载请注明文章出处:http://www.cnblogs.com/magic-zero/p/5787181.html 起初看到这个漏洞的时候是在exploit-db上边.地址在这里:https://w ...

  4. SqlServer数据库《基本》

    数据库简单说就是行.列组成的二维表 把列称为字段.每一行数据成为记录,能标识每一行的唯一字段称为主键 查询数据表时,索引可以提高查询速度,但是索引同时会降低新增和更新数据时的速度,应为还要更新索引. ...

  5. @RequestMapping的value属性

    package com.zby.controller; import javax.servlet.http.HttpServletRequest; import org.springframework ...

  6. ptyhon技能树及其学习资源

    GUI编程 tkinter Github项目 Tkinter by example effbot 文档 tkinter的一个designer,可以像在qtdesign那样创建UI文件 pyqt5 py ...

  7. $bzoj1019-SHOI2008$ 汉诺塔 $dp$

    题面描述 汉诺塔由三根柱子(分别用\(A\ B\ C\)表示)和\(n\)个大小互不相同的空心盘子组成.一开始\(n\)个盘子都摞在柱子\(A\)上,大的在下面,小的在上面,形成了一个塔状的锥形体. ...

  8. 【爬虫】-xpath语法熟悉及实战

    本文为自学记录,部分内容转载于 w3school python3网络爬虫实战 知乎专栏:写点python 如有侵权,请联系删除. 语法 1.选取节点 XPath 使用路径表达式在 XML 文档中选取节 ...

  9. JavaScript跨浏览器处理事件以及相关对象

    主流的浏览器和IE浏览器在处理事件和事件对象上是有所区别的,我们一般会通过EventUtil进行封装,这样,就可以正常的跨浏览器处理事件了,本文的主要内容总结自<JavaScript高级程序设计 ...

  10. Flexbox 完全指南

    Flexbox 完全指南 我不是这篇文章的原创作者,我只是好文章的搬运工.原文地址 A Complete Guide to Flexbox 应用于 flex container 的属性 display ...