|

楼主 |
发表于 2020-3-16 15:41:35
|
显示全部楼层
研究了一晚上算是找到了点点规律,发出来大家共同学习=。=
(不一定对,有错误请大佬指正)
首先,我们先手算一下n为6时所有可能的序列(当然你也可以用代码)
- 6 1
- 6 1 1
- 6 1 2
- 6 1 3
- 6 1 3 1
- 6 1 3 1 1
- 6 1 4
- 6 1 4 1
- 6 1 4 1 1
- 6 1 4 1 2
- 6 1 4 2
- 6 1 4 2 1
- 6 2
- 6 2 1
- 6 2 2
- 6 2 3
- 6 3
- 6 3 1
- 6 3 1 1
- 6 3 2
- 6 4
- 6 4 1
- 6 4 1 1
- 6 4 1 2
- 6 5
- 6 6
复制代码
我们可以发现:
当 4 1 的后面分支都是相同的(我也表达不明白,看图)
可以得出:
当前一个数(a)和后一个数(b)相同时,产生的结果数也是相同的
于是我们将结果数保存在一个二维数组中,下一次要用时直接取用
经过测试,有效的减少了运算量,对于n=1000也能1s内得出结果
(虽然我也不知道答案是否准确就对了,希望有做出不同思路的大佬能跟我校对下答案)
贴下我优化后的代码
- #include <iostream>
- #include <cmath>
- //#include <ctime>
- using namespace std;
- int buff[1001][1001];
- //clock_t clSt, clEd;
- int ca(int a, int b)
- {
- if (buff[a][b] != 0) {
- //由于ab相同后续的可能性也相同,这里我直接取用之前保存的结果数
- return buff[a][b];
- }
- int ab = abs(a - b);
- int c;
- int count = 1;
- for (c = 1; c < ab; c++)
- {
- //cout << a << '\t' << b << '\t' << c << endl;
- count += ca(b, c);
- }
- count %= 10000;//每次都对结果取余,防止溢出(可能。。。还是会溢出)
- buff[a][b] = count;//保存结果
- return count;
- }
- int main()
- {
- int n;
- cin >> n;
- //初始化
- //clSt = clock();
- int ret = 0;
- for (int i = 0; i < n; i++)
- {
- for (int j = 0; j < n; j++)
- {
- buff[i][j] = 0;
- }
- }
- //第二个数
- for (int i = 1; i <= n; i++)
- {
- //cout << n << '\t' << i << endl;
- ret += ca(n, i);
- }
- ret %= 10000;
- //clEd = clock();
- cout << ret << endl;
- //double runtime = (double)(clEd - clSt) / CLOCKS_PER_SEC;
- //cout << "用时:" << runtime << endl;
- return 0;
- }
复制代码
|
|