Matches |
We can make digits with matches as shown below:
Given N matches, find the number of different numbers representable using the matches. We shall only make numbers greater than or equal to 0, so no negative signs should be used. For instance, if you have 3 matches, then you can only make the numbers 1 or 7. If you have 4 matches, then you can make the numbers 1, 4, 7 or 11. Note that leading zeros are not allowed (e.g. 001, 042, etc. are illegal). Numbers such as 0, 20, 101 etc. are permitted, though.
Input
Input contains no more than 100 lines. Each line contains one integer N (1 ≤ N ≤ 2000).
Output
For each N, output the number of different (non-negative) numbers representable if you have N matches.
Sample Input
3
4
Sample Output
2
4
Problemsetter: Mak Yan Kei
题意:用n跟火柴能组成多少个非负整数,其中火柴不必用完。其中
0——6根火柴
1——2根火柴
2——5根火柴
3——5根火柴
4——4根火柴
5——5根火柴
6——6根火柴
7——3根火柴
8——7根火柴
9——6根火柴
分析:
本题利用递推关系解决。首先可以把“已经使用过的火柴数i”看做状态,可以得到一个图,从前往后每添加一个数字x,就从状态i转移到了i+c[x],其中c[x]代表数字x需要的火柴数。当i=0时不允许使用数字0(当n≥6,给答案单独加上1,代表整数0)。令d(i)表示从结点0到结点i的路径条数,则答案为f(n)=d(1)+d(2)+...+d(n)。初始化的时候d(0) = 1。
程序实现时,我们可以按照从小到大的顺序用d(i)更新所有的d(i+c[j])(j取遍数字0~9)。由于结果非常大, 需要使用高精度模板存储结果。
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 using namespace std; 5 #define MAX_N 2000 6 int n; 7 int c[] = {6,2,5,5,4,5,6,3,7,6}; 8 struct Node{ 9 int p[500]; 10 int len; 11 Node(){ 12 memset(p,0,sizeof p); len = 0; 13 } 14 Node(int a){ 15 p[0] = a; 16 len = 1; 17 } 18 Node operator +(const Node& a)const{ 19 Node b; 20 b.len = max(len,a.len); 21 for(int i = 0 ; i < b.len ; i++){ 22 b.p[i] += p[i] + a.p[i]; 23 b.p[i + 1] = b.p[i] / 10; 24 b.p[i] %= 10; 25 } 26 if (b.p[b.len] > 0) b.len++; 27 return b; 28 } 29 void out(){ 30 if (!len) puts("0"); 31 else{ 32 for(int i = len - 1 ; i >= 0 ; i--) printf("%d", p[i]); 33 puts(""); 34 } 35 } 36 }d[MAX_N + 1]; 37 void init(){ 38 d[0].p[0] = 1; 39 d[0].len = 1; 40 for(int i = 0 ; i < MAX_N + 1 ; i++){ 41 for(int j = 0 ; j < 10 ; j++) 42 if (i + c[j] < MAX_N + 1 && !(i == 0 && j == 0)) //i=j=0时不允许转移 43 d[i + c[j]] = d[i + c[j]] + d[i]; 44 } 45 d[6] = d[6] + Node(1); 46 for(int i = 2 ; i < MAX_N + 1 ; i++) 47 d[i] = d[i] + d[i - 1]; 48 } 49 int main(){ 50 init(); 51 while(cin >> n) d[n].out(); 52 return 0; 53 }