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

 Input
  第一行一个正整数n
  1<=n<=10^5
 Output
  一个非负整数表示答案,你需要将答案对23333333取模

 
首先我们可以发现,令S=sqrt(n),那么对于大小大于S的物品,其实是用不完的,我们可以把他们的数量视为无限个

对于大小小于S的物品,我们可以令f[i][j]表示考虑了前i个物品,总大小为j的方案数,那么有:
f[i][j]=sum{f[i-1][j-k*i]},0<=k<=i
我们在DP的时候,假设当前要计算f[i][j],可以设tmp[v]为当前满足t mod i=v的f[i-1][t]的和
然后就可以通过维护tmp数组,轻松计算出f[i][j]了
这一步的时间复杂度是O(nsqrt(n))
 
接下来考虑大小大于S的物品

我们考虑一个给物品“动态添加大小”的DP:
令g[i][j]表示,当前有i个物品,大小总和为j
我们可以做的转移是:
(1):将所有物品的大小加一 :g[i][j]->g[i][j+i]
(2):新建一个大小为S+1的物品g[i][j]->g[i+1][j+S+1]
可以发现,物品总数最多为n/S个,所有g的第一维的规模是n/S的,所以这一个DP也是O(n*sqrt(n))的
于是总复杂度就是O(n*sqrt(n))
这道题还有更加优美的算法,可以用多项式黑科技进行推导,可以得到复杂度O(nlogn)的做法,由于出题人能力有限所以这里就不阐述了
 
 #include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<cmath>
#define ll long long
#define ui unsigned int
#define ull unsigned long long
const int maxn=,modd=;
int f[][maxn],g[][maxn],sm[maxn],tmp[maxn];
int i,j,k,n,m,n1; int ra;char rx;
inline int read(){
rx=getchar(),ra=;
while(rx<''||rx>'')rx=getchar();
while(rx>=''&&rx<='')ra*=,ra+=rx-,rx=getchar();return ra;
} #define MOD(x) x-=x>=modd?modd:0
#define UPD(x) x+=x<0?modd:0
int main(){
n=read(),n1=sqrt(n);register int i,j,k; bool now=,pre=;f[][]=;int mod;
for(i=;i<=n1;i++,std::swap(now,pre)){
memset(tmp,,i<<),mod=-;
for(j=,k=-i*i;j<=n;j++,k++){
if(++mod>=i)mod=;
tmp[mod]+=f[pre][j],MOD(tmp[mod]),
f[now][j]=tmp[mod];
if(k>=)tmp[mod]-=f[pre][k],UPD(tmp[mod]);
}
}//printf("n1:%d\n",n1);
//for(i=1;i<=n;i++)printf(" %d",f[pre][i]);puts("");
int n2=n/n1;
bool now1=,pre1=;g[][]=;
for(i=;i<=n2;i++,std::swap(now1,pre1)){
memset(g[now1],,(n1+)<<);
for(j=n1+,k=;j<=n;j++,k++)g[now1][j]=g[pre1][k];
for(j=i;j<=n;j++)g[now1][j]+=g[now1][j-i],MOD(g[now1][j]);
for(j=;j<=n;j++)sm[j]+=g[now1][j],MOD(sm[j]);
}
int ans=f[pre][n]+sm[n];MOD(ans);
for(i=;i<n;i++)ans=(ans+1ll*f[pre][i]*sm[n-i])%modd;
printf("%d\n",ans);
}

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

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

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

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

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

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

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

  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. go defer (go延迟函数)

    go defer (go延迟函数) Go语言的defer算是一个语言的新特性,至少对比当今主流编程语言如此.根据GO LANGUAGE SPEC的说法: A "defer" sta ...

  2. Eclipse多行同时进行编辑,可编辑或修改相同内容

    使用Shift+Alt+A可以进入Eclipse多行编辑的功能,选中的一部分区域从光标开始处同时进行修改或者插入功能. 再次按下Shift+Alt+A可已退出该编辑模式.

  3. vue使用国际化

    转载请注明作者与出处 一:安装vue-i18n npm install vue-i18n --save 二:定义不同语言的json语言包 一般把它放到npm工程中的src目录下,因为这个目录是要进行编 ...

  4. 调用CMD命令的一个.NET工具类(MyWindowsCmd)

    功能大概描述一下如果直接StandardOutput.ReadToEnd()这种方法,有很多限制 这类方式必须把命令全部执行一次写入并标记为exit,而且返回内容的获取会一直等待,如果在主线程里使用会 ...

  5. PredictionIO+Universal Recommender快速开发部署推荐引擎的问题总结(1)

    1,PredictionIO如果用直接下载的0.11.0-incubating版本,存在一个HDFS配置相关的BUG 执行pio status命令时会发生如下的错误: -- ::, ERROR org ...

  6. String 转化成java.sql.Date和java.sql.Time

    String类型转换成java.sql.Date类型不能直接进行转换,首先要将String转换成java.util.Date,在转化成java.sql.Date 请点击--->   java架构 ...

  7. Python函数篇(7)-正则表达式

    1.正则表达式   正则表达式为高级的文本模式匹配,抽取,与/或文本形式的搜索和替换功能提供了基础,简单的来说,正则表达式是由一些字符和特殊符号组成的字符串.Python通过标准库中的re模块来支持正 ...

  8. maven 打包Could not resolve dependencies for project和无效的目标发行版: 1.8

    1.maven 打包Could not resolve dependencies for project 最近项目上使用的是idea ide的多模块话,需要模块之间的依赖,比如说系统管理模块依赖授权模 ...

  9. Webpack 2 视频教程 015 - Webpack 2 中的文件压缩

    原文发表于我的技术博客 这是我免费发布的高质量超清「Webpack 2 视频教程」. Webpack 作为目前前端开发必备的框架,Webpack 发布了 2.0 版本,此视频就是基于 2.0 的版本讲 ...

  10. springBoot系列教程04:mybatis及druid数据源的集成及查询缓存的使用

    首先说下查询缓存:查询缓存就是相同的数据库查询请求在设定的时间间隔内仅查询一次数据库并保存到redis中,后续的请求只要在时间间隔内都直接从redis中获取,不再查询数据库,提高查询效率,降低服务器负 ...