🐏🐏🐏
🐏动态规划之计数类DP🐏
🐏写在前面🐏
之前讲过背包问题,线性DP,区间DP,不知道大家忘了吗,这次是计数类DP
看完本篇文章觉得不错的话记得点赞👍,收藏⭐,还有问题也可以评论留言💬
这篇文章可能有点水,因为最近挺多事的,不能保证每篇都是高质量的了,但小🐏又不想断了每天一篇博客,所以等我有时间了,我一定会优化内容的,如果有问题的可以评论留言哦。
🐏石子合并🐏
老规矩,先画图。
思路:把1,2,3, … n分别看做n个物体的体积,这n个物体均无使用次数限制,问恰好能装满总体积为n的背包的总方案数(完全背包问题变形)
初值问题:
求最大值时,当都不选时,价值显然是 0
而求方案数时,当都不选时,方案数是 1(即前 i 个物品都不选的情况也是一种方案),所以需要初始化为 1
即:for (int i = 0; i <= n; i ++) f[i][0] = 1;
等价变形后: f[0] = 1
状态计算:
f[i][j]表示前i个整数(1,2…,i)恰好拼成j的方案数
求方案数:把集合选0个i,1个i,2个i,…全部加起来
f[i][j] = f[i - 1][j] + f[i - 1][j - i] + f[i - 1][j - 2 * i] + …;
f[i][j - i] = f[i - 1][j - i] + f[i - 1][j - 2 * i] + …;
因此 f[i][j]=f[i−1][j]+f[i][j−i]; (这一步类似完全背包的推导)
朴素做法
// f[i][j] = f[i - 1][j] + f[i][j - i]
#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 7, mod = 1e9 + 7;
int f[N][N];
int main() {
int n;
cin >> n;
for (int i