dp[i][j]dp[i][j]表示长度为ii,以字符结尾的答案是多少
对于普通的来说,一个经典的转移方程
dp[i][j]=∑mk=0(dp[i−1][k]∗2−dp[pre[j]−1][k])dp[i][j]=∑k=0m(dp[i−1][k]∗2−dp[pre[j]−1][k])
那么对于这个式子,所有的jj是等价的,对于所有的,总能找到一个dp[i][j]dp[i][j],并且这些串的数量应该是之前所有的串之和,所以式子可以化简为
dp[i]=dp[i−1]∗2m−dp[i−1]dp[i]=dp[i−1]∗2m−dp[i−1]
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <set>
#include <cmath>
#include <map>
#include <sstream>
#define LL long long
#define INF 0x3f3f3f3f
#define mod 1000000007
#define eps 1e-6
const int maxn = 500000 + 5;
using namespace std;
int maps[105][105][105];
int main(){
int n,m;
scanf("%d%d",&n,&m);
LL ans = 2*m;
LL temp = 1;
for(int i=2; i<=n; i++){
temp = temp * m % mod;
ans = (ans * (2*m - 1) % mod + temp + mod) % mod;
}
printf("%lld\n",ans);
}
组合数学太弱了,不太会推。。也看不太懂