京东9.17笔试第三题
简单dp,dp[i][a][b][k]表示i位的字符串,第i位为a,第i-1位为b,之前是否已经含有red(k为1表示有,0表示无) 的方案数,可以使用滚动数组优化掉第一维度
时间复杂度为 n*26*26*26*2,会t掉。故需要优化,可以考虑对字母进行压缩,分别用0,1,2,3来表示字母 r,e,d,其他字母 。这样时间复杂度可以降为n*4*4*4*2 ,具体转移方程可以看代码
#include <bits/stdc++.h> using namespace std; #define endl '\n' #define int long long const int mod = 1e9 + 7; signed main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; vector<vector<vector<int>>> dp(5, vector<vector<int>>(5, vector<int>(2, 0))); for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) dp[i][j][0] = (i == 3 ? 23 : 1) * (j == 3 ? 23 : 1); // R,E,D,$ for (int i = 2; i < n; i++){ vector<vector<vector<int>>> rdp(5, vector<vector<int>>(5, vector<int>(2, 0))); for (int c = 0; c < 4; c++) for (int b = 0; b < 4; b++) for (int a = 0; a < 4; a++){ if (c == 2 && b == 1 && a == 0)//der不转移 continue; rdp[a][b][(c == 0 && b == 1 && a == 2) ? 1 : 0] += dp[b][c][0] * (a == 3 ? 23 : 1); rdp[a][b][1] += dp[b][c][1] * (a == 3 ? 23 : 1); rdp[a][b][0] %= mod, rdp[a][b][1] %= mod; } dp = rdp; } int ans = 0; for (int i = 0; i < 4; i++) for (int j = 0; j < 4; j++) ans += dp[i][j][1], ans %= mod; cout << ans << endl; }