[计数dp] 整数划分(模板题+计数dp+完全背包变种题)
计数类 dp 可分为 计数 dp 和数位统计 dp。大多是用来统计方案数什么的,特别强调 不重不漏,在此还是根据各个题的特点将计数 dp 和数位 dp 分开整理。其实数位 dp 的题目会相对多很多…
计数dp 模板题
AcWing 900.整数划分

重点: 计数 dp、完全背包问题抽象
首先模拟下样例便于理解本题:
5 = 5
= 4 + 1
= 3 + 2
= 3 + 1 + 1
= 2 + 1 + 1 + 1
= 2 + 2 + 1
= 1 + 1 + 1 + 1 + 1
共七种划分方式
故我们可以将问题抽象为一个容量为 n 的背包,有 n 个体积为 1 ~ n 的物品,求恰好将该背包的方案数。每种物品可以使用无限次,故该问题是一个完全背包问题。
思路:
- 状态定义:
f[i][j]:从 1~i 中选,且总体积恰好为 j 的选法数量
- 状态转移:
- 分类依据:根据最后一个物品选择个数进行状态划分,和完全背包问题的状态划分一致。
- 第 i 个物品选 0 个:
f[i-1][j] - 第 i 个物品选 1 个:
f[i-1][j - i] - 第 i 个物品选 2 个:
f[i-1][j - 2*i] - 第 i 个物品选 s 个:
f[i-1][j - s*i]
- 第 i 个物品选 0 个:
- 至此,朴素版完全背包问题就到此为止。但是,完全背包问题有一个非常厉害的优化方式。建议阅读:[背包] 背包问题算法模板(模板)
f[i][j] = f[i-1][j]+f[i-1][j-1]+f[i-1][j-i*2]+...+f[i-1][j-i*s]f[i][j-i] = f[i-1][j-i]+f[i-1][j-i*2] +..+ f[i-1][j-i*s]- 仔细对比,发现 f[i][j-i] 和 f[i][j] 的后半段一样,故:
f[i][j] = f[i-1][j] + f[i][j-i]
- 故状态转移方程为:
f[i][j]=f[i-1][j]+f[i][j-i] - 和完全背包问题一样,也可以优化掉第一维,即 f[i]=f[j]+f[j-i]。体积从小到大循环即可
- 分类依据:根据最后一个物品选择个数进行状态划分,和完全背包问题的状态划分一致。
- 状态初始化:f[0]=1,一个数都不选的方案是 1
完全背包代码:
const int mod = 1e9 + 7;
void solve() {
int n;
cin >> n;
int f[n + 1] = {1};
for (int i = 1; i <= n; ++i)
for (int j = i; j <= n; ++j)
f[j] = (f[j] + f[j - i]) % mod;
cout << f[n] << endl;
}
除了完全背包的写法及状态定义外,也有一种其它的状态定义方式,状态转移方程不同但是却能得到相同的结果…
思路:
- 状态定义:
f[i][j]:所有总和是 i,并且恰好表示成 j 个数的和的方案的数量
- 状态转移:
- 分类依据:根据表示成的这 j 个数中是否包含 1,来进行集合划分
- 如果包含 1,等价于
f[i-1][j-1],等价于和是 i-1 数量是 j-1 的选法数量 - 如果每个数大于 1,则等价于将这 j 个数全部减去一个 1,则总数减去了 j,其和 f[i-j][j] 方案数相等。
- 如果包含 1,等价于
- 故状态转移方程
f[i][j] = f[i-1][j-1]+f[i-j][j] - 答案即为
ans = f[n][1] + f[n][2] +...+f[n][n]
- 分类依据:根据表示成的这 j 个数中是否包含 1,来进行集合划分
- 状态初始化:
f[0][0] = 1代表总和是 0 的时候选 0 个的方案数是 1
代码:
const int mod = 1e9 + 7;
const int N = 1e3 + 10;
int f[N][N];
void solve() {
int n;
cin >> n, f[0][0] = 1;
for (int i = 1; i <= n; ++i)
for (int j = 1; j <= i; ++j)
f[i][j] = (f[i - 1][j - 1] + f[i - j][j]) % mod;
int ans = 0;
for (int i = 1; i <= n; ++i)ans = (ans + f[n][i]) % mod;
cout << ans << endl;
}
故可看出,同一个 dp 问题,不同的思考方式,不同的集合划分,不同的状态转移方程,只有思路是正确的,那么就是可行的。当然,在本题,划分方式不同导致了状态转移方程的不同,进而导致了求解答案时也不同。
参考
[计数dp] 整数划分(模板题+计数dp+完全背包变种题)的更多相关文章
- NYOJ90 整数划分(经典递归和dp)
整数划分 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1. 正 ...
- HDU 1028 Ignatius and the Princess III dp整数划分
http://acm.hdu.edu.cn/showproblem.php?pid=1028 dp[i][j]表示数值为i,然后最小拆分的那个数是j的时候的总和. 1 = 1 2 = 1 + 1 . ...
- 51nod 1201:整数划分 超级好的DP题目
1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} { ...
- HDU 5230 ZCC loves hacking 大数字的整数划分
http://acm.hdu.edu.cn/showproblem.php?pid=5230 把题目简化后,就是求 1---n - 1这些数字中,将其进行整数划分,其中整数划分中不能有重复的数字,如果 ...
- HDU4632 Poj2955 括号匹配 整数划分 P1880 [NOI1995]石子合并 区间DP总结
题意:给定一个字符串 输出回文子序列的个数 一个字符也算一个回文 很明显的区间dp 就是要往区间小的压缩! #include<bits/stdc++.h> using namesp ...
- 51nod 1201 整数划分 基础DP
1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 收藏 关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} ...
- hdu 5230 整数划分 dp
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5230 题意:给定n,c,l,r.求有多少种方法从1~n-1选取任意k数每个数的权重为其下标,使得这些数字之 ...
- 【noi 2.6_8787】数的划分(DP){附【转】整数划分的解题方法}
题意:问把整数N分成K份的分法数.(与"放苹果"不同,在这题不可以有一份为空,但可以类比)解法:f[i][j]表示把i分成j份的方案数.f[i][j]=f[i-1][j-1](新开 ...
- 整数划分 (区间DP)
整数划分(四) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...
- 51nod 1201 整数划分 dp
1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 收藏 关注 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2,4} {1,2 ...
随机推荐
- JavaWeb项目练习(学生选课管理系统)一
打算做一个选课管理系统,作为期末的复习. 上需求 2.1 页面要求 (1)系统可以通过浏览器直接访问:(1分) (2)各个功能页面整体风格统一:(2分) (3)首页为用户登录页面,管理员.教师.学生三 ...
- [ABC318G] Typical Path Problem
Problem Statement You are given a simple connected undirected graph $G$ with $N$ vertices and $M$ ed ...
- c标签的使用问题
这是在使用c标签的时候遇到的问题,发现在导入包成功的情况下,jsp页面代码也没有问题.在网页上查了查,发现需要修改tomcat中的 conf/catalina.properties文件. 将tomca ...
- Git提交修正
应用场景 日常开发中我们可能会遇到这样的问题 1.提交了代码有错误 2.提交的信息写错了 3.漏了一些文件没有提交 ...... 再或者我们写一个功能时,中间有很多小的提交,这中间就会产生特别多的co ...
- 51Nod - 1086 多重背包
有N种物品,每种物品的数量为C1,C2......Cn.从中任选若干件放在容量为W的背包里,每种物品的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi ...
- 神经网络优化篇:详解梯度消失/梯度爆炸(Vanishing / Exploding gradients)
梯度消失/梯度爆炸 训练神经网络,尤其是深度神经所面临的一个问题就是梯度消失或梯度爆炸,也就是训练神经网络的时候,导数或坡度有时会变得非常大,或者非常小,甚至于以指数方式变小,这加大了训练的难度. 接 ...
- CVE-2022-39197 复现
CVE-2022-39197 ️漏洞介绍 Cobalt Strike (CS) 是一个为对手模拟和红队行动而设计的平台,相当于增强版的Armitage,早期以Metasploit为基础框架,3.0版本 ...
- 探索 Linux Namespace:Docker 隔离的神奇背后
在 深入理解 Docker 核心原理:Namespace.Cgroups 和 Rootfs 一文中我们分析了 Docker 是由三大核心技术实现的. 今天就一起分析 Docker 三大核心技术之一的 ...
- zabbix-server 报错记录
数据库磁盘满导至zabbix挂了 登陆zabbix页面提示错误信息,查看系统磁盘: /目录已满,导致mariadb数据库无法正常运行,如果有介质将会一直收取: 解决方法:扩容/目录,达到理想值,重启m ...
- ElasticSearch的简单api介绍
1:ElasticSearch是什么? Elasticsearch 是一个分布式的免费开源搜索和分析引擎 适用于包括文本.数字.地理空间.结构化和非结构化数据等在内的所有类型的数据 Elasticse ...