#1855 : 合法數字
- 樣例輸入
-
2
- 樣例輸出
-
26
描述
小Hi的手機屏幕上有0-9十個數字,按如下方式排列:
1 2 3 4 5 6 7 8 9 0
每當小Hi輸入一個數字之後,下一個輸入數字只能是其上下左右4個相鄰數字之一。
例如123是合法的輸入,而122和124都不是合法的。
請你計算合法的N位輸入一共有多少個? 由於結果可能非常大,你只需要輸出結果除以1000000007的餘數。
注意第一位可以是0-9中任意一位。
輸入
一個整數N。
1 ≤ N ≤ 100000
輸出
一個整數表示答案。
思路:
顯然當N = 1的時候 只有9中情況,當N等於2的時候,取決於N=1時的每個字母。也就是說數字的第 位的情況,取決於第 位的情況。所以我們用 表示數字共 位 且以 結尾的數字總數。那麼轉移方程爲 其中 表示下一步狀態可以到達 的數字。比如 時, 那麼 。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <vector>
using namespace std;
const int mod = 1e9+7;
long long dp[100005][10];
int solve(int n) {
memset(dp, 0, sizeof(dp));
for (int i = 0; i <= 9; ++i)
dp[1][i] = 1;
long long res = 0;
for (int i = 2; i <= n; ++i) {
for (int j = 0; j <= 9; ++j) {
if (j == 1)
dp[i][j] = (dp[i-1][2] + dp[i-1][4]) % mod;
else if (j == 2)
dp[i][j] = (dp[i-1][1] + dp[i-1][3] + dp[i-1][5]) % mod;
else if (j == 3)
dp[i][j] = (dp[i-1][2] + dp[i-1][6]) % mod;
else if (j == 4)
dp[i][j] = (dp[i-1][1] + dp[i-1][5] + dp[i-1][7]) % mod;
else if (j == 5)
dp[i][j] = (dp[i-1][2] + dp[i-1][4] + dp[i-1][6] + dp[i-1][8]) % mod;
else if (j == 6)
dp[i][j] = (dp[i-1][5] + dp[i-1][9] + dp[i-1][3]) % mod;
else if (j == 7)
dp[i][j] = (dp[i-1][4] + dp[i-1][8]) % mod;
else if (j == 8)
dp[i][j] = (dp[i-1][0] + dp[i-1][5] + dp[i-1][7] + dp[i-1][9]) % mod;
else if (j == 9)
dp[i][j] = (dp[i-1][6] + dp[i-1][8]) % mod;
else
dp[i][j] = (dp[i-1][8]) % mod;
//cout << i << "<<dp[i][j] <<
}
}
res = 0;
for (int i = 0; i <= 9; ++i) {
res = (res + dp[n][i]) % mod;
}
cout << res << endl;
return 0;
}
int main() {
int n;
cin >> n;
solve(n);
return 0;
}