(leetcode) 2478. 完美分割的方案数( dp )
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了(leetcode) 2478. 完美分割的方案数( dp )相关的知识,希望对你有一定的参考价值。
题意
把一个字符串切割为k段, 每段至少长minLength, 且段以一个质数开始, 以非质数结束.
问切割方案. ( n<=2000)
定义 f [ i ] [ j ] f[i][j] f[i][j]表示把前 i i i个字符分为 j j j段的方案
这样每次转移需要枚举一个 q q q让 [ q + 1 , j ] [q+1,j] [q+1,j]自成一段, 转移为
f [ i ] [ j ] + = f [ q ] [ j − 1 ] f[i][j] +=f[q][j-1] f[i][j]+=f[q][j−1]
复杂度为 O ( n 3 ) O(n^3) O(n3), 不过这个转移显然是可以优化的.
观察这个转移, 符合条件的 q q q是
q < = i − m i n L e n g t h & & s [ q ] ∈ [ 2 , 3 , 5 , 7 ] q<=i-minLength\\ \\ \\&\\&\\ \\ s[q]\\in[2,3,5,7] q<=i−minLength && s[q]∈[2,3,5,7]
那么新开一个前缀和数组, p r e [ i ] [ j ] = ∑ q < = i & & s [ q ] ∈ [ 2 , 3 , 5 , 7 ] f [ q ] [ j ] pre[i][j]=\\sum\\limits_q<=i\\&\\&s[q]\\in[2,3,5,7] f[q][j] pre[i][j]=q<=i&&s[q]∈[2,3,5,7]∑f[q][j](这里 s [ q ] s[q] s[q]表示第 q + 1 q+1 q+1个字符)
转移为(当 s [ i − 1 ] s[i-1] s[i−1]不为质数时)
f [ i ] [ j ] = p r e [ i − m i n L e n g t h ] [ j − 1 ] f[i][j] = pre[i-minLength][j-1] f[i][j]=pre[i−minLength][j−1]
然后其实这个 p r e pre pre数组很好维护. 因为根据转移, 用到的 i − m i n L e n g t h i-minLength i−minLength是递增的
所以此时可以把 p r e [ i − m i n L e n g t h ] [ . . . . . ] pre[i-minLength][.....] pre[i−minLength][.....]的值视为已知, 转移为
p r e [ i ] [ j − 1 ] = p r e [ i − 1 ] [ j − 1 ] + f [ i − m i n L e n g t h ] [ j − 1 ] pre[i][j-1] = pre[i-1][j-1]+f[i-minLength][j-1] pre[i][j−1]=pre[i−1][j−1]+f[i−minLength][j−1]
复杂度 O ( n 2 ) O(n^2) O(n2)
class Solution
public:
static const int maxn = 2009;
const int mod = 1e9+7;
int pre[maxn][maxn],f[maxn][maxn];
bool iszhi(char c)
int x = c-'0';
if( x!=2 && x!=3 && x!=5 && x!=7 )
return false;
return true;
int beautifulPartitions(string s, int k, int minLength)
/*
f[i][j]表示前i个字符分为j段的方案
从f[q][j-1]转移而来, 要求q+1是质数, j是非质数
pre[x][j]表示q<=x, 且x+1为质数的f[q][j]和
*/
f[0][0] = 1;
int n = s.size();
for(int i=minLength;i<=n;i++)
int zhi = iszhi( s[i-1] );
int x = i-minLength;
for(int j=1;j<=i;j++)
if( x-1>=0 )
pre[x][j-1] = pre[x-1][j-1];
if( iszhi( s[i-minLength] ) )
pre[x][j-1] = ( pre[x][j-1]+f[i-minLength][j-1] )%mod;
if( !zhi )
f[i][j] = pre[i-minLength][j-1]; // f[q][j-1]的和, 满足q+1为质数
if( iszhi( s[i] ) ) pre[i+minLength][j] += f[i][j];
return f[n][k];
;
以上是关于(leetcode) 2478. 完美分割的方案数( dp )的主要内容,如果未能解决你的问题,请参考以下文章