整数划分——计数类dp

900. 整数划分 - AcWing题库

 

计数类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 }
View Code

 

posted @ 2022-03-29 16:19  wellerency  阅读(36)  评论(0编辑  收藏  举报