一. 题目
二. 思路
1. DP
若t的大小在1s内跑完,可使用此方法。
f[i,j]:执行i此转换后,字符j的数量。
f[i+1, nj]+=f[i,j],i->i+1不用预处理i-1到i时i,j由谁转移了。
2. 矩阵快速幂优化DP
三. 代码
1. DP
class Solution
{
static final int M = 30, MOD = (int) 1e9 + 7;
int[][] f = new int[2][M];
public int lengthAfterTransformations(String s, int t, List<Integer> nums)
{
for (Character c : s.toCharArray())
++f[0][c - 'a'];
for (int i = 0; i < t; ++i)
{
Arrays.fill(f[i + 1 & 1], 0);//记得清空
for (int j = 0; j < 26; ++j)
for (int k = 1; k <= nums.get(j); ++k)
f[i + 1 & 1][(j + k) % 26] = (f[i + 1 & 1][(j + k) % 26] + f[i & 1][j]) % MOD;
}
int ans = 0;
for (int i = 0; i < 26; ++i)
ans = (ans + f[t & 1][i]) % MOD;
return ans;
}
}
2. 矩阵快速幂优化DP
class AK
{
static final int N = 26, MOD = (int) 1e9 + 7;
int[][] a = new int[N][N];
static AK getOne()//得到单位矩阵
{
AK o = new AK();
for (int i = 0; i < N; ++i)
o.a[i][i] = 1;
return o;
}
AK mul(AK o)//自身X另一个矩阵
{
AK res = new AK();
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
for (int k = 0; k < N; ++k)
res.a[i][j] = (int) ((res.a[i][j] + (long) a[i][k] * o.a[k][j]) % MOD);
return res;
}
static AK qmi(AK a, int k)//快速幂
{
AK ans = getOne();
while (k > 0)
{
if ((k & 1) == 1) ans = ans.mul(a);
a = a.mul(a);
k >>= 1;
}
return ans;
}
}
class Solution
{
int[] f = new int[AK.N];
public int lengthAfterTransformations(String s, int t, List<Integer> nums)
{
for (Character c : s.toCharArray())//得到f[0]
++f[c - 'a'];
AK T = new AK();
for (int i = 0; i < AK.N; ++i)//得到初始T
for (int j = 1; j <= nums.get(i); ++j)
T.a[(i + j) % 26][i] = 1;
AK res = AK.qmi(T, t);//得到快速幂后的T
int ans = 0;
for (int i = 0; i < AK.N; ++i)//最后一次乘
for (int j = 0; j < AK.N; ++j)
ans = (int) ((ans + (long) res.a[i][j] * f[j]) % AK.MOD);
return ans;
}
}