博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
51nod-有限背包计数问题【dp】
阅读量:2022 次
发布时间:2019-04-28

本文共 1235 字,大约阅读时间需要 4 分钟。

正题

题目链接:


题目大意

n n n种物品,第 i i i个大小为 i i i且有 i i i个。

求恰好填满大小为 n n n的背包的方案数


解题思路

我们可以将背包分为两份,对于大小小于等于 n \sqrt n n 的物品,这样的物品数量不超过 n n n\sqrt n nn 个,所以我们可以用多重背包来做,这里要优化,我们将 f i , j f_{i,j} fi,j中根据 j % i j\%i j%i的不同来进行分组,这样只有组内可以相互转移且是在一个区间内转移,可以 O ( n n ) O(n\sqrt n) O(nn )的计算出答案,然后反向枚举压缩掉 i i i这一维就有方程(u枚举余数

f u + p ∗ i = ∑ p − i ≤ k ≤ p − 1 f u + k ∗ i f_{u+p*i}=\sum_{p-i\leq k\leq p-1}f_{u+k*i} fu+pi=pikp1fu+ki

然后对于大于 n \sqrt n n 的物品,我们可以将其视为有无限个物品,所以我们可以将问题变为求将一个数字分解成若干个可以相同但是要大于 n \sqrt n n 的数字的和的方案数。

考虑一个集合,每次可以加入一个数字(物品) n + 1 \sqrt n+1 n +1或者全体数字都 + 1 +1 +1(物品都变大一个)。

然后设 g i , j g_{i,j} gi,j表示目前集合内数字和(选择的物品和)为 i i i,然后集合内数字(物品)个数为 j j j,就有方程 g i , j = g i − n − 1 , j + g i , j − 1 g_{i,j}=g_{i-\sqrt n-1,j}+g_{i,j-1} gi,j=gin 1,j+gi,j1

然后转移即可


c o d e code code

#include
#include
#include
#include
using namespace std;const int N=1e5+10,XJQ=23333333;int n,T,f[N],g[2][N],s[N],ans;int main(){
scanf("%d",&n);T=sqrt(n)+1; f[0]=1; for(int i=1;i
max(t-i,-1);p--) (sum+=f[u+i*p])%=XJQ; for(int p=t;p>=0;p--){
if(p-i>=0)sum=(sum+f[u+i*(p-i)])%XJQ; sum=(sum-f[u+i*p]+XJQ)%XJQ; f[u+p*i]=(f[u+p*i]+sum)%XJQ; } } } g[0][0]=s[0]=1; for(int i=1;i

转载地址:http://jdwaf.baihongyu.com/

你可能感兴趣的文章
[Android]ListView美化:去阴影、底色、选中色
查看>>
Hadoop C++ Pipes中context常见成员函数的作用
查看>>
Hadoop Streaming 实战: 文件分发与打包
查看>>
Spring4+quartz2集群借助邮箱或是短信实现生日的农历提醒(Quartz实现农历、阴历、公历生日提醒)...
查看>>
防止页面后退(使浏览器后退按钮失效)
查看>>
浅谈CAS在分布式ID生成方案上的应用
查看>>
Navicat MySQL建表设置时间戳,createtime字段自动添加为当前时间
查看>>
用js实现禁用浏览器的后退按钮
查看>>
android4.0 USB Camera实例(六)ffmpeg mpeg编码
查看>>
crm使用soap操作商机赢单
查看>>
offsetTop clientX pageX screenX scrollTop之间的差别以及代码实现
查看>>
Kotlin修行之路——基本语法
查看>>
在VS2003中编写控制台程序的方法,以及自动缩进快捷键: CTRL+K+F
查看>>
CString, QString, char*之间的转换
查看>>
漫说单例模式--宝宝成长记 你真的了解了吗?
查看>>
生产者/消费者问题的多种Java实现方式--转
查看>>
Java 序列化和反序列化
查看>>
Spring事务配置的五种方式【转】
查看>>
[转]利用 Linux crontab 定时执行 PHP
查看>>
新人讨论一:事务和两阶段提交
查看>>