计数dp原理

计数DP

整数划分

一个正整数 n n n可以表示成若干个正整数之和 我们将这样的一种表示称为正整数n的一种划分。

现在给定一个正整数n,请你求出n共有多少种不同的划分方法。

完全背包写法

状态表示

类似完全背包 1 ~ i 1~i 1i分为 i i i个物品 每个物品的体积为 i i i 并且不限制数量 求总体积为 j j j的方案数

f [ i ] [ j ] f[i][j] f[i][j]表示从 1 ~ i 1~i 1i选总体积恰好为 j j j的数量

状态计算

f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i − 1 ] [ j − i ] + f [ i − 1 ] [ j − i ∗ 2 ] + ⋯ + f [ i − 1 ] [ j − s ∗ i ] f[i][j] \qquad = f[i-1][j] + f[i - 1][j - i] + f[i-1][j - i * 2]+\cdots + f[i-1][j - s * i] f[i][j]=f[i1][j]+f[i1][ji]+f[i1][ji2]++f[i1][jsi]

f [ i ] [ j − i ]     = f [ i − 1 ] [ j − i ] + f [ i − 1 ] [ j − i ∗ 2 ] + ⋯ + f [ i − 1 ] [ j − s ∗ i ] f[i][j - i] \ \,= \qquad \qquad \quad f[i - 1][j - i] + f[i - 1][j - i * 2] + \cdots + f[i -1 ][j - s*i] f[i][ji] =f[i1][ji]+f[i1][ji2]++f[i1][jsi]

∴ \therefore f [ i ] [ j ] = f [ i − 1 ] [ j ] + f [ i ] [ j − i ] f[i][j] = f[i - 1][j] + f[i][j - i] f[i][j]=f[i1][j]+f[i][ji]

优化成一维

与完全背包类似 从小到大枚举即可

f [ j ] = f [ j ] + f [ j − i ] f[j] = f[j] + f[j - i] f[j]=f[j]+f[ji]

const int N = 1010;
int f[N];

int main() {
   
	int n;cin >> n;

	f[0] = 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;
	return 0;
}

另一种解法

状态表示

所有总和是 i i i并且恰好表示成 j j j个数的和的方案

状态计算

分成两种情况

①最小值为1 去掉一个1 得 f [ i − 1 ] [ j − 1 ] f[i - 1][j - 1] f[i1][j1]表示 j − 1 j-1 j1个数的和为 i − 1 i-1 i1

②最小值大于1 每个数都减去1 得 f [ i − j ] [ j ] f[i - j][j] f[ij][j] 表示 j j j个数的和为 i − j i-j ij

∴ \therefore f [ i ] [ j ] = f [ i − 1 ] [ j − 1 ] + f [ i − j ] [ j ] f[i][j] = f[i - 1][j - 1] + f[i - j][j] f[i][j]=f[i1][j1]+f[ij][j]

const int N = 1010;
int f[N][N];

int main() {
   
	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 res = 0;
	for (int i = 1;i <= n;++i)res = (res + f[n][i]) % mod;

	cout << res << endl;

	return 0;
}
全部评论

相关推荐

仁者伍敌:实习生要工作经验,工作要实习经验
点赞 评论 收藏
分享
07-14 13:47
门头沟学院 Java
Lynn012:你评估好自己的位置了吗《顶尖应届》
投递小米集团等公司7个岗位
点赞 评论 收藏
分享
流浪的神仙:无恶意,算法一般好像都得9硕才能干算法太卷啦
点赞 评论 收藏
分享
zYvv:双一流加大加粗再标红,然后广投。主要是获奖荣誉不够,建议开始不用追求大厂,去别的厂子刷下实习。
点赞 评论 收藏
分享
不愿透露姓名的神秘牛友
07-10 12:05
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务