给定一个自然数N,要求把N拆分成若干个正整数相加的形式,参与加法运算的数可以重复。
注意:
- 拆分方案不考虑顺序;
- 至少拆分成2个数的和。
求拆分的方案数 mod 2147483648的结果。
输入格式
一个自然数N。
输出格式
输入一个整数,表示结果。
数据范围
1≤N≤4000
输入样例:
7
输出样例:
14
思路:将一个数差分成若干个数,很显然其中某些数可能会出现多次, 就是说这些数可以用无限多次来构成最初的数,这就是完全背包问题:有n个物品,每个物品可以选无限多次,求选出的若干个物品的价值之和恰好为n的方案个数。
状态表示:用f[i,j]表示选前i个物品且总价值之和恰好为j的方案,维护的属性:count。
状态计算:将f[i,j]按当前i(集合的最后一件物品)选和不选划分为两部分,前一部分:f[i-1,j];
后一部分:因为每件物品可能选多次,所以还要考虑次数,所这一部分方案数为:f[i,j-vi]+f[i,j-2vi]+...
因此,总的方案数为f[i,j]=f[i-1,j]+(f[i,j-vi]+f[i,j-2vi]+...),但是这样就要再枚举每件物品选的次数,时间复杂度变成o
(n^3),所以要再进一步优化:
通过对比观察f[i,j]和f[i,j-vi]代入上式的结果发现:f[i,j]=f[i-1,j]+f[i,j-vi]+f[i,j-2vi]+...
&

这篇博客探讨了如何使用完全背包问题的方法来解决将自然数N拆分成若干正整数相加的问题,其中拆分的方案不考虑顺序,至少拆成两个数的和。博主给出了数据范围(1≤N≤4000),并提供了思路和优化后的状态转移方程,以降低时间复杂度。文章最后提到了完整的代码实现。
676

被折叠的 条评论
为什么被折叠?



