动态规划的代码复杂度是O(N),其中N为号码的长度
其实用矩阵乘法更快点,初始矩阵rela[j]表示用1步从i到j的可能情况数(初始是1),最后就是先求矩阵的7次方,然后对res[j]求和就行了,一次矩阵乘法的计算次数是10^3=1000次乘法,矩阵乘法用优化算法是log(N-1)次,所以计算次数大概是1000log(N-1)+100(100是对res[j]求和),也就是说,复杂度大概是O(logN),代码如下,结果求出是14826:- #include <stdio.h>
- #include <string.h>
- int rela[10][10] = {{0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
- {0, 0, 1, 0, 1, 0, 0, 0, 0, 0},
- {0, 1, 0, 1, 0, 1, 0, 0, 0, 0},
- {0, 0, 1, 0, 0, 0, 1, 0, 0, 0},
- {0, 1, 0, 0, 0, 1, 0, 1, 0, 0},
- {0, 0, 1, 0, 1, 0, 1, 0, 1, 0},
- {0, 0, 0, 1, 0, 1, 0, 0, 0, 1},
- {0, 0, 0, 0, 1, 0, 0, 0, 1, 0},
- {1, 0, 0, 0, 0, 1, 0, 1, 0, 1},
- {0, 0, 0, 0, 0, 0, 1, 0, 1, 0}};
- int res[10][10], len = 7, i, j, ans;
- void
- mult(int s[][10], int t[][10]) {
- int temp[10][10], i, j, k;
- for (i = 0; i < 10; ++i)
- for (j = 0; j < 10; ++j) {
- temp[i][j] = 0;
- for (k = 0; k < 10; ++k)
- temp[i][j] += s[i][k] * t[k][j];
- }
- memcpy(s, temp, sizeof(temp));
- }
- int
- main()
- {
- for (i = 0; i < 10; ++i)
- res[i][i] = 1;
- for (i = 1; ; ) {
- if (len & i)
- mult(res, rela);
- if ((i <<= 1) > len)
- break;
- else
- mult(rela, rela);
- }
- for (i = ans = 0; i < 10; ++i)
- for (j = 0; j < 10; ++j)
- ans += res[i][j];
- fprintf(stdout, "%d\n", ans);
- return 0;
- }
复制代码 相比起动态规划,我认为矩阵乘法是最优的了 |