E - RLE
题意:
有一种字符串转换方式,例如
“
a
a
a
b
b
c
c
c
c
”
“aaabbcccc”
“aaabbcccc”可以转换为
“
a
3
b
2
c
4
”
“a3b2c4”
“a3b2c4”
求长度为
n
n
n的字符串,有多少种不同的字符串可以使转换后的字符串长度小于
n
n
n
思路:
动态规划
令
f
[
i
]
[
j
]
f[i][j]
f[i][j]为长度为
i
i
i的字符串,转换后的长度为
j
j
j,有多少种情况
c
a
l
(
x
)
cal(x)
cal(x)表示连续
x
x
x个相同的字母组成的字符串转换成新串后的长度
最最简单的
d
p
dp
dp转移办法即
f
[
i
]
[
j
]
=
∑
f
[
i
−
k
]
[
j
−
c
a
l
(
k
)
]
f[i][j]=\sum f[i-k][j-cal(k)]
f[i][j]=∑f[i−k][j−cal(k)]
时间复杂度为
O
(
n
3
)
O(n^3)
O(n3),无法通过本题
其实也不难发现
c
a
l
(
1
)
=
c
a
l
(
2
)
=
.
.
.
=
c
a
l
(
9
)
=
1
c
a
l
(
10
)
=
c
a
l
(
11
)
=
.
.
.
=
c
a
l
(
99
)
=
2
.
.
.
cal(1)=cal(2)=...=cal(9)=1\\cal(10)=cal(11)=...=cal(99)=2\\...
cal(1)=cal(2)=...=cal(9)=1cal(10)=cal(11)=...=cal(99)=2...
于是
f
[
i
]
[
j
]
=
(
f
[
i
−
1
]
[
j
−
1
]
+
.
.
.
+
f
[
i
−
9
]
[
j
−
1
]
)
∗
25
f
[
i
]
[
j
]
=
(
f
[
i
−
10
]
[
j
−
2
]
+
.
.
.
+
f
[
i
−
99
]
[
j
−
2
]
)
∗
25
.
.
.
f[i][j]=(f[i-1][j-1]+...+f[i-9][j-1])*25\\f[i][j]=(f[i-10][j-2]+...+f[i-99][j-2])*25\\...
f[i][j]=(f[i−1][j−1]+...+f[i−9][j−1])∗25f[i][j]=(f[i−10][j−2]+...+f[i−99][j−2])∗25...
注意特判开始的情况,字符串开始的连续区间有
26
26
26种
使用前缀和优化
d
p
dp
dp即可在
O
(
n
2
)
O(n^2)
O(n2)的时间解决问题
#include<bits/stdc++.h>
typedef long long ll;
using namespace std;
ll f[3005][3005],sum[3005][3005];
ll cal(ll x)
{
if(x<10) return 2;
else if(x<100) return 3;
else if(x<1000) return 4;
else return 5;
}
ll n,mod;
int main()
{
scanf("%lld%lld",&n,&mod);
f[0][0]=1;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
if(cal(i)==j)
{
f[i][j]+=26;f[i][j]%=mod;
}
if(j>2&&i>1)
{
int u=max(0,i-10);
f[i][j]+=((sum[i-1][j-2]-sum[u][j-2])%mod+mod)%mod*25;
f[i][j]%=mod;
}
if(j>3&&i>10)
{
int u=max(0,i-100);
f[i][j]+=((sum[i-10][j-3]-sum[u][j-3])%mod+mod)%mod*25;
f[i][j]%=mod;
}
if(j>4&&i>100)
{
int u=max(0,i-1000);
f[i][j]+=((sum[i-100][j-4]-sum[u][j-4])%mod+mod)%mod*25;
f[i][j]%=mod;
}
if(j>5&&i>1000)
{
int u=max(0,i-10000);
f[i][j]+=((sum[i-1000][j-5]-sum[u][j-5])%mod+mod)%mod*25;
f[i][j]%=mod;
}
sum[i][j]=sum[i-1][j]+f[i][j];
sum[i][j]%=mod;
}
}
ll ans=0;
for(int i=1;i<n;i++)
{
ans+=f[n][i];
ans%=mod;
}
printf("%lld\n",ans);
}