整数划分(完全背包)

 

将正整数n示成一系列正整数之和: n= n1 +n2 +... + nk,中n1≥n2≥...≥Nk≥1,k≥1。

正整数n的这种表示称为正整数n的划分。求正整数n的不同划分个数。

例如正整数6有如下11种不同的划分: 

6、5+1、4+2、 4+1+1、3+3、 3+2+1、3+1+1+1、2+2+2、 2+2+1+1、2+1+1+1+1、1+1+1+1+1+1。

输入格式

第一行是测试数据的数目M(1≤M≤10)。以下每行均包含一个整数n(1 ≤n≤100000)。

输出格式

输出每组测试数据有多少种分法,最终结果模109 + 9。

输入样例

1
6

输出样例

11

 

这是一个完全背包,每个数可以用无数次。

 

 1 #include <stdio.h>
 2 #include <string.h>
 3 #include <iostream>
 4 #include <string>
 5 #include <math.h>
 6 #include <algorithm>
 7 #include <vector>
 8 #include <stack>
 9 #include <queue>
10 #include <set>
11 #include <map>
12 #include <sstream>
13 #include <ctime>
14 const int INF=0x3f3f3f3f;
15 typedef long long LL;
16 const int mod=1e9+9;
17 const LL MOD=1e9+7;
18 const double PI = acos(-1);
19 const double eps =1e-8;
20 #define Bug cout<<"---------------------"<<endl
21 const int maxn=1e5+10;
22 using namespace std;
23 
24 LL dp[maxn];
25  
26 int main()
27 {
28     #ifdef DEBUG
29     freopen("sample.txt","r",stdin);
30     #endif
31 //    ios_base::sync_with_stdio(false);
32 //    cin.tie(NULL);
33     
34     int T;
35     scanf("%d",&T);
36     while(T--)
37     {
38         memset(dp,0,sizeof(dp));
39         dp[0]=1;
40         int n;
41         scanf("%d",&n);
42         for(int i=1;i<=n;i++)
43         {
44             for(int j=i;j<=n;j++)
45                 dp[j]=(dp[j]+dp[j-i])%mod;
46         }
47         printf("%lld\n",dp[n]);
48     }
49     
50     return 0;
51 }

 

 

 

-

posted @ 2020-01-20 17:17  jiamian22  阅读(514)  评论(0编辑  收藏  举报