整数划分——计数类dp
计数类dp在目前我的理解里,就是状态表示中的属性是数量的dp。这道题就是一个完全背包问题的变形,完全背包问题求的是每种物品无限次使用后的最大代价(注意是这个状态表示的属性是max),而本题求的是每种数字无限次使用后能表示成一个特定的数的数量。
本题的公式推导与完全背包问题差不多。
状态表示为使用i种数字后总和为j的方案数量。
f [ i , j ]= f [ i -1 ,j ] + f [ i- 1 , j - 1 *i ] + f [ i- 1, j -2 * i ] + f [ i - 1 , j - ... * i ]
f [ i , j - i ] = f [ i - 1 , j- 1 *i ] + f [ i - 1 , j - 2 * i ] + f [ i - 1, j - ... * i ]
所以 f [ i , j] = f [i , j- i ] +f [ i -1 , j ]
那我们就可以将二维转化为一维,简化为 f [ j ] = f [ j ] +f [ j - i ]
注意,我们还要初始化 f [ 0 ] 为1,因为 f[ i ] [ 0] 表示使用i种数字,但是总和为0的方案数量,应该为1.

1 #include <bits/stdc++.h> 2 using namespace std; 3 const int N=1e3+100,mod=1e9+7;; 4 int f[N]; 5 6 int main() 7 { 8 int n;scanf("%d",&n); 9 10 f[0]=1; 11 for(int i=1;i<=n;i++) 12 for(int j=i;j<=n;j++) 13 f[j]=(f[j]+f[j-i])%mod; 14 15 printf("%d\n",f[n]); 16 17 return 0; 18 }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探