GCPC2014 J Not a subsequence

题意:给你一个字符串,问你含有 k个字符集合 长度最短的不是字符串子序列的种类数和长度。

解题思路:DP.很难想  site[i] 表示以i 开头的使得 串不再字符串中的最小长度 ,dp[i] 表示种类数。  状态转移方程在代码里面。

解题代码:

  1 // File Name: j.4.cpp
  2 // Author: darkdream
  3 // Created Time: 2015年03月20日 星期五 16时43分43秒
  4 
  5 #include<vector>
  6 #include<list>
  7 #include<map>
  8 #include<set>
  9 #include<deque>
 10 #include<stack>
 11 #include<bitset>
 12 #include<algorithm>
 13 #include<functional>
 14 #include<numeric>
 15 #include<utility>
 16 #include<sstream>
 17 #include<iostream>
 18 #include<iomanip>
 19 #include<cstdio>
 20 #include<cmath>
 21 #include<cstdlib>
 22 #include<cstring>
 23 #include<ctime>
 24 #include<climits>
 25 #define LL long long
 26 #define maxn 1000005
 27 #define M 1000000007
 28 using namespace std;
 29 int t, k;
 30 char str[maxn];
 31 int hs[600];
 32 int ok[64];
 33 int nxt[64];
 34 int dp[maxn];
 35 int site[maxn];
 36 int sum[maxn];
 37 int main(){  
 38     for(int i = 'a' ;i <= 'z' ;i ++)
 39     {
 40         hs[i] = i - 'a';
 41     }
 42     for(int i = 'A' ;i <= 'Z'; i++)
 43     {
 44         hs[i] = i - 'A' + 26; 
 45     }
 46     for(int i = '0' ;i <= '9'; i ++)
 47     {
 48         hs[i] = i - '0' + 52;
 49     }
 50     scanf("%d",&t);
 51     while(t--)
 52     {
 53         scanf("%d %s",&k,str);
 54         int len = strlen(str);
 55         memset(ok,0,sizeof(int)*k);
 56         sum[0] = 0;
 57         int wei = 0 ;
 58         memset(nxt,-1,sizeof(int)*k);
 59         int twei = 0 ;
 60         int tt;
 61         for(int i = len -1;i >= 0 ;--i)
 62         {
 63             site[i] = wei;  
 64             tt = nxt[hs[str[i]]] ;
 65             if(wei){
 66                 sum[wei] = (sum[wei]+sum[wei-1])%M;
 67                 dp[i] = sum[wei-1];
 68                 if(site[tt] != wei)
 69                 {
 70                     sum[wei-1] = (sum[wei-1]-dp[tt]+M)%M;
 71                 }else{
 72                     sum[wei] = (sum[wei]-dp[tt]+M)%M;
 73                 }
 74             }else{
 75                 sum[wei] += k-twei;
 76                 dp[i] = k -twei;
 77                 if(tt != -1)
 78                 {
 79                     sum[wei] -= dp[tt];
 80                 }
 81             }
 82             if(ok[hs[str[i]]] == 0)
 83             {
 84               ok[hs[str[i]]] = 1;
 85               twei ++ ;
 86             }
 87             if(twei == k )    
 88             {
 89               wei ++ ;
 90               twei = sum[wei] = 0 ;
 91               memset(ok,0,sizeof(int)*k);
 92             }
 93             nxt[hs[str[i]]] = i ; 
 94         }
 95         if(!wei){
 96             printf("1 %d
",k-twei);
 97         }else{
 98             printf("%d %d
",wei+1,sum[wei-1]);    
 99         }
100     }
101 return 0;
102 }
View Code
没有梦想,何谈远方
原文地址:https://www.cnblogs.com/zyue/p/4354548.html