トピックリンク:ここをクリック〜
トピック
- n以下で、サブシーケンス「us」を含む小文字で構成される文字列はいくつありますか?答えはモジュロ1e9 + 7です。
- サブシーケンス、私たちは隣接していない可能性があります
- 範囲:2≤n≤1e6
アイデア
- dpを使用して状態を転送します。ここでポイントをプッシュするために数式を見ると-
- 定義: dp [i] [0]は、長さiの文字列にuがないことを意味し、dp [i] [1]は、長さiの文字列にuがあるが、sがないことを意味します。dp[i] [2]は、長さiサブシーケンスがあります。
- 初期化: dp [1] [0] = 25、dp [1] [1] = 1、dp [1] [2] = 0。
- 状態遷移: dp [i] [0] = dp [i-1] [0] * 25(前にuはなく、現在のビットでuが選択されていません)
- dp [i] [1] = dp [i-1] [0](前にuはなく、現在の位置はuです)+ dp [i-1] [1] * 25(uは前に選択されていますが、 s、現在は選択しないでくださいs)
- dp [i] [2] = dp [i-1] [1](以前はuがありましたが、sはありません。現在の位置はsです)+ dp [i-1] [2] * 26(以前はすでに私たちがいます) 、現在はいずれかを選択してください)
- 長さがnを超えないため、dp [i] [2]はすべて要件を満たします
ACコード
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int mod = 1e9 + 7;
const int maxn = 1e6 + 5;
ll dp[maxn][5];
int main(){
int n; cin >> n;
dp[1][0] = 25; //无u
dp[1][1] = 1; //有u无s
dp[1][2] = 0; //有us
ll ans = 0;
for(int i = 2; i <= n; i ++){
dp[i][0] = dp[i - 1][0] * 25 % mod;
dp[i][1] = (dp[i - 1][0] + dp[i - 1][1] * 25 % mod) % mod;
dp[i][2] = (dp[i - 1][1] + dp[i - 1][2] * 26 % mod) % mod;
ans = (ans + dp[i][2]) % mod;
}
cout << ans << endl;
return 0;
}