zoukankan      html  css  js  c++  java
  • AtCoder Beginner Contest 171 F 另类题解

    ABC171F链接

    可以发现一个字符串 (T) 能被 (S) 形成,当且仅当 (len_T = len_S + k)(S)(T) 的子序列。

    考虑暴力 (dp)(dp_{i,j}) 表示考虑到第 (i) 位,已经有 (j) 位匹配了 (S) 的方案数。

    (S) 的长度为 (m) ,则:

    [ dp_{i,j}=left{ egin{array}{rcl} dp_{i-1,j-1} + 25dp_{i-1,j} & & {j < m}\ dp_{i-1,j-1} + 26dp_{i-1,j} & & {j = m}\ end{array} ight. ]

    打个表,可以发现:

    [dp_{i,j} = C_i^j imes 25^{i-j} (j < m) ]

    考虑用这样的方法,算出所有 (dp_{i,m-1}) 的值,然后用它们推出所有 (dp_{i,m}) 的值。

    (O(n + m))

    #include<bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    #define mit map<int,int>::iterator
    #define sit set<int>::iterator
    #define itrm(g,x) for(mit g=x.begin();g!=x.end();g++)
    #define itrs(g,x) for(sit g=x.begin();g!=x.end();g++)
    #define ltype int
    #define rep(i,j,k) for(ltype(i)=(j);(i)<=(k);(i)++)
    #define rap(i,j,k) for(ltype(i)=(j);(i)<(k);(i)++)
    #define per(i,j,k) for(ltype(i)=(j);(i)>=(k);(i)--)
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define mpr make_pair
    #define pb push_back
    #define fastio ios::sync_with_stdio(false)
    const int inf=0x3f3f3f3f,mod=1000000007;
    const double pi=3.1415926535897932,eps=1e-6;
    void chmax(int &x,int y){if(x < y) x = y;}
    void chmin(int &x,int y){if(x > y) x = y;}
    int n,m,f[2000005],g[2000005],fac[2000005],inv[2000005];
    char s[2000005];
    int qpow(int x,int y){
        int res = 1;
        while(y) {
            if(y & 1) res = (ll)res * x % mod;
            x = (ll)x * x % mod;
            y >>= 1;
        }
        return res;
    }
    int C(int x,int y) {
        return (ll)fac[x] * inv[y] % mod * inv[x - y] % mod;
    }
    int main()
    {
        scanf("%d",&n);
        scanf("%s",s);
        m = strlen(s);
        fac[0] = 1;
        rep(i,1,n+m) fac[i] = (ll)fac[i-1] * i % mod;
        inv[n + m] = qpow(fac[n + m], mod - 2);
        per(i,n+m-1,0) {
            inv[i] = (ll)inv[i + 1] * (i + 1) % mod;
        }
    
        //dp[0][0] = 1;
        /*rep(i,1,n + m) rep(j,0,min(i,m))  {
            if(j != m) {
                dp[i][j] = dp[i-1][j] * 25ll % mod;
                if(j) {dp[i][j] += dp[i-1][j-1];if(dp[i][j] >= mod) dp[i][j] -= mod;}
            }
            else {
                dp[i][j] = dp[i-1][j] * 26ll % mod;
                if(j) {dp[i][j] += dp[i-1][j-1];if(dp[i][j] >= mod) dp[i][j] -= mod;}
            }
        }
        printf("%d
    ",dp[n+m][m]);*/
        rep(i,m-1,n+m) {
            f[i] = (ll)C(i, m - 1) * qpow(25, i - m + 1) % mod;
        }
        rep(i,m,n+m){
            g[i] = (g[i - 1] * 26ll % mod + f[i - 1]) % mod;
        }
        printf("%d
    ",g[n + m]);
        return 0;
    }
    
  • 相关阅读:
    常见排序算法导读(8)[堆排序]
    常见排序算法导读(7)[希尔排序]
    常见排序算法导读(6)[快排序]
    常见排序算法导读(5)[冒泡排序]
    常见排序算法导读(4)[直接插入排序]
    UI基础
    iOS8之后CoreLocation定位的使用
    关于什么时候用pop什么时候用dismiss
    控制台输出文字改中文
    Quartz2D使用
  • 原文地址:https://www.cnblogs.com/yz-beacon-cwk/p/13198018.html
Copyright © 2011-2022 走看看