[计数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 ...
随机推荐
- Flask 使用Jinja2模板引擎
Jinja2,由Flask框架的创作者开发,是一款功能丰富的模板引擎,以其完整的Unicode支持.灵活性.高效性和安全性而备受推崇.最初受Django模板引擎启发,Jinja2为Flask提供了强大 ...
- GPTs 初体验 - 1 分钟就能创建一个自己的 ChatGPT?
就在 11.10 号早上,ChatGPT 已经偷摸的把GPTs功能,开放给所有尊贵的 Plus 用户了. 随着这波的功能开放,界面也是改了不少.点击左侧的 Explore 或者左下角的用户处,就可以直 ...
- C#简化工作之实现网页爬虫获取数据
公众号「DotNet学习交流」,分享学习DotNet的点滴. 1.需求 想要获取网站上所有的气象信息,网站如下所示: 目前总共有67页,随便点开一个如下所示: 需要获取所有天气数据,如果靠一个个点开再 ...
- 神经网络入门篇:详解随机初始化(Random+Initialization)
当训练神经网络时,权重随机初始化是很重要的.对于逻辑回归,把权重初始化为0当然也是可以的.但是对于一个神经网络,如果把权重或者参数都初始化为0,那么梯度下降将不会起作用. 来看看这是为什么. 有两个输 ...
- Axure实战应用:Axure设计可视化大屏!
Axure是一款功能强大的原型设计工具,可以用于设计可视化大屏.设计一个有效的可视化大屏需要考虑多个方面,包括布局规划.信息展示.交互设计等. 以下是一个详细的描述,希望对你有所帮助. 第一部分:可视 ...
- netty整合websocket(完美教程)
websocket的介绍: WebSocket是一种在网络通信中的协议,它是独立于HTTP协议的.该协议基于TCP/IP协议,可以提供双向通讯并保有状态.这意味着客户端和服务器可以进行实时响应,并且这 ...
- MySQL索引命名规范
[强制]主键索引名为 pk_字段名:唯一索引名为 uk_字段名:普通索引名则为 idx_字段名 说明:pk_ 即 primary key:uk_ 即 unique key:idx_ 即 index 的 ...
- 华企盾DSC防泄密软件:svn、git更新后有感叹号常见处理方法
1.查看客户端日志检查TSVNcache.exe进程是否是legal:1 2.TSVNcache.exe进程是否允许访问未配置加密进程的后缀 3.svn服务器不是加密进程也未装网络驱动,或者加密类型未 ...
- Salesforce LWC学习(四十七) 标准页面更新以后自定义页面如何捕捉?
本篇参考: https://developer.salesforce.com/docs/atlas.en-us.platform_events.meta/platform_events/platfor ...
- adb shell getprop 获取系统属性
adb shell getprop 以华为p30为例: [gsm.default.apn]: [gsm.defaultpdpcontext.active]: true [gsm.dualcards.s ...