zoukankan      html  css  js  c++  java
  • 【考试题

    题意:给定一个字符串,求有多少个子序列满足该子序列长度为 $7$,且位置所对应字母在子序列中排名为 3652415.   

    观察发现如果枚举 $3,5,2$ 上的字母的话其他字母插入方式只有 1 种,即不会引起冲突.   

    然后就令 $f[x][i]$ 表示 DP 到 $i$ 位置,匹配了子序列第 $x$ 位置的方案数,转移方式只有 1 种.  

    严格来说,这个的复杂度是 $O(26^3 imes 7n)$ 的,但是枚举 $2,3,5$ 的时候可以严格限制好上界,常数较小,能卡过. 

    code: 

    #include <cstdio>   
    #include <vector>
    #include <cstring>
    #include <algorithm>    
    #define N 100008 
    #define ll long long 
    #define mod 3652415 
    #define setIO(s) freopen(s".in","r",stdin) 
    using namespace std;  
    char str[N]; 
    int mx,n,f[8],ans,a[N]; 
    void calc(int s2,int s3,int s5) {  
        memset(f,0,sizeof(f)); 
        for(int i=1;i<=n;++i) { 
            if(a[i]==s3) ++f[1];  
            if(a[i]>s5)  (f[2]+=f[1])%=mod;   
            if(a[i]==s5) {  
                (f[3]+=f[2])%=mod;  
                (f[7]+=f[6])%=mod; 
            }  
            if(a[i]==s2) (f[4]+=f[3])%=mod;  
            if(a[i]>s3&&a[i]<s5) { 
                (f[5]+=f[4])%=mod; 
            }  
            if(a[i]<s2) (f[6]+=f[5])%=mod;    
        }
        (ans+=f[7])%=mod; 
    }
    int main() { 
        // setIO("input");  
        scanf("%s",str+1);  
        n=strlen(str+1); 
        for(int i=1;i<=n;++i) mx=max(mx,str[i]-'a');  
        for(int i=1;i<=n;++i) a[i]=str[i]-'a'; 
        for(int i=1;i+4<=mx;++i) { 
            for(int j=i+1;j+3<=mx;++j) { 
                for(int k=j+2;k+1<=mx;++k) 
                    calc(i,j,k); 
            }
        } 
        printf("%d
    ",ans); 
        return 0; 
    }
    

      

  • 相关阅读:
    HDU5000 (DP + 规律)
    HDU5127 神坑题---vector 、 list 、 deque 的用法区别
    HDU5128 细心、细心、细心
    dij单源最短路纯模板
    POJ 1236 SCC+缩点
    SCC(强连通分量)
    用树状数组求数组内的逆序对数
    HDU 1811 并查集
    大数模板,只要不是手敲,非常好用
    市赛
  • 原文地址:https://www.cnblogs.com/guangheli/p/13397490.html
Copyright © 2011-2022 走看看