[51nod1597]有限背包计数问题
你有一个大小为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]有限背包计数问题的更多相关文章
- 2018.09.25 51nod1597 有限背包计数问题(背包+前缀和优化)
传送门 dp好题. 我认为原题的描述已经很清楚了: 你有一个大小为n的背包,你有n种物品,第i种物品的大小为i,且有i个,求装满这个背包的方案数有多少. 两种方案不同当且仅当存在至少一个数i满足第i种 ...
- 51Nod 有限背包计数问题 题解报告
首先这道题理论上是可以做到O(nlogn)的,因为OEIS上有一个明显可以用多项式乘法加速的式子 但是由于模数不是很兹磁,所以导致nlogn很难写 在这里说一下O(n*sqrt(n))的做法 首先我们 ...
- 51Nod1957 有限背包计数问题
传送门 另一个传送门 这题还挺有意思…… 先贴一波出题人的题解…… (啥你说你看不见?看来你还没过啊,等着A了再看或者乖乖花点头盾好了……) 然后是我的做法……思想都是一样的,只是细节不一样而已…… ...
- 51nod 1597 有限背包计数问题 (背包 分块)
题意 题目链接 Sol 不会做啊AAA.. 暴力上肯定是不行的,考虑根号分组 设\(m = \sqrt{n}\) 对于前\(m\)个直接暴力,利用单调队列优化多重背包的思想,按\(\% i\)分组一下 ...
- 题解 51nod 1597 有限背包计数问题
题目传送门 题目大意 给出 \(n\),第 \(i\) 个数有 \(i\) 个,问凑出 \(n\) 的方案数. \(n\le 10^5\) 思路 呜呜呜,傻掉了... 首先想到根号分治,分别考虑 \( ...
- LOJ #6089. 小 Y 的背包计数问题
LOJ #6089. 小 Y 的背包计数问题 神仙题啊orz. 首先把数分成\(<=\sqrt n\)的和\(>\sqrt n\)的两部分. \(>\sqrt n\)的部分因为最多选 ...
- 【LOJ6089】小Y的背包计数问题(动态规划)
[LOJ6089]小Y的背包计数问题(动态规划) 题面 LOJ 题解 神仙题啊. 我们分开考虑不同的物品,按照编号与\(\sqrt n\)的关系分类. 第一类:\(i\le \sqrt n\) 即需要 ...
- LOJ6089 小Y的背包计数问题(根号优化背包)
Solutioon 这道题利用根号分治可以把复杂度降到n根号n级别. 我们发现当物品体积大与根号n时,就是一个完全背包,换句话说就是没有了个数限制. 进一步我们发现,这个背包最多只能放根号n个物品. ...
- LOJ6089 小Y的背包计数问题 背包、根号分治
题目传送门 题意:给出$N$表示背包容量,且会给出$N$种物品,第$i$个物品大小为$i$,数量也为$i$,求装满这个背包的方案数,对$23333333$取模.$N \leq 10^5$ $23333 ...
随机推荐
- linux使用freetds 连接连远程服务器sqlservser2012
1.下载:freetds-patched.tar.gz http://www.freetds.org/software.html http://www.freetds.org/userguide/c ...
- rtmp指令解释--转
指令 Core rtmp 语法:rtmp { ... } 上下文:根 描述:保存所有 RTMP 配置的块. server 语法:server { ... } 上下文:rtmp 描述:声明一个 RTMP ...
- lesson - 14 linux系统日常管理3
1. Linux系统服务管理工具ntsysv 类似图形界面管理工具,如果没有该命令使用 yum install -y ntsysv 安装常用服务:crond, iptables, network, s ...
- 测试库的接收到的数据是否完整(jrtplib为列)
最近使用jrtplib来接收RTP包,然后解码播放 发现解码出来的是绿屏,马赛克 于是开始排查 首先直接用wireshark抓进来的包,转为可以被vlc播放的文件 操作如下 http://blog.c ...
- vexx 邀请码 送3个比特龙
错过了比特币的行情,注册获取3个原始比特币分叉币,比特龙. 目前10元一个,送3个币.类似于股票IPO,第一天一般会冲高十几倍,建议第一天就卖. 如果看好就继续持有吧. 放心是送的不用钱的. 注册网址 ...
- 阻止form空表单提交----JavaScript
网上看到很不错的阻止form空表单提交 第一种方法 <div class="warp"> <h2>登录到pfan空间</h2> <p> ...
- Hibernate学习笔记(5)---Query接口
Hibernate中具有三种检索方式(HQL,QBC,SQL) Query接口 一个查询接口,用于向数据库中查询对象.并控制执行查询的过程.Query接口内封装了一个HQL查询语句. 举个栗子 //查 ...
- IOS 看懂此文,你的block再也不需要WeakSelf弱引用了!
前言: 最近都在折腾 Sagit 架框的内存释放的问题,所以对这一块有些心得. 对于新手,学到的文章都在教你用:typeof(self) __weak weakSelf = self. 对于老手,可能 ...
- 小白的Python之路 day5 shutil模块
shutil模块 一.主要用途 高级的文件.文件夹.压缩包 等处理模块 二.常用方法详解 1.shutil.copyfileobj(fsrc, fdst) 功能:把一个文件的内容拷贝到另外一个文件中, ...
- docker with flannel
** 原创文章,请勿转载 ** docker的单host,多container环境下,是使用host的docker0网桥进行通信的.如果跨host, container之间要通信怎么办呢?答案是fla ...