题意:
给一个小写字母组成的串,问长度为$K$的不重复的子序列有多少个。
思路:
$dp[i][j]$表示长度为$i$的最后一位为$j$的子序列的个数。
转移方程为:$dp[i][j]=sum_{k=0}^{25}{dp[i-1][k]}$。
特判$K=0$时个数为$1$。
代码:
1 #include<bits/stdc++.h> 2 #include <set> 3 #include <map> 4 #include <stack> 5 #include <cmath> 6 #include <queue> 7 #include <cstdio> 8 #include <string> 9 #include <vector> 10 #include <cstring> 11 #include <iostream> 12 #include <algorithm> 13 14 #define ll long long 15 #define pll pair<ll,ll> 16 #define pii pair<int,int> 17 #define bug printf("********* ") 18 #define FIN freopen("input.txt","r",stdin); 19 #define FON freopen("output.txt","w+",stdout); 20 #define IO ios::sync_with_stdio(false),cin.tie(0) 21 #define ls root<<1 22 #define rs root<<1|1 23 #define Q(a) cout<<a<<endl 24 25 using namespace std; 26 const int inf = 2e9 + 7; 27 const ll Inf = 1e18 + 7; 28 const int maxn = 1e6 + 5; 29 const int mod = 1e9 +7; 30 31 ll gcd(ll a, ll b) 32 { 33 return b ? gcd(b, a % b) : a; 34 } 35 36 ll lcm(ll a, ll b) 37 { 38 return a / gcd(a, b) * b; 39 } 40 41 ll read() 42 { 43 ll p = 0, sum = 0; 44 char ch; 45 ch = getchar(); 46 while (1) 47 { 48 if (ch == '-' || (ch >= '0' && ch <= '9')) 49 break; 50 ch = getchar(); 51 } 52 53 if (ch == '-') 54 { 55 p = 1; 56 ch = getchar(); 57 } 58 while (ch >= '0' && ch <= '9') 59 { 60 sum = sum * 10 + ch - '0'; 61 ch = getchar(); 62 } 63 return p ? -sum : sum; 64 } 65 66 ll dp[maxn][50]; 67 char s[maxn]; 68 69 int main() 70 { 71 int n,k; 72 scanf("%d %d",&n,&k); 73 scanf("%s",s+1); 74 if(k==0) 75 { 76 printf("1 "); 77 return 0; 78 } 79 for(int i=1;i<=n;++i) 80 { 81 int x=s[i]-'a'; 82 for(int j=i;j>=1;--j) 83 { 84 ll res=0; 85 for(int o=0;o<26;++o) 86 { 87 res+=dp[j-1][o]; 88 res%=mod; 89 } 90 dp[j][x]=res; 91 // cout<<j<<" "<<(char)(x+'a')<<" "<<dp[j][x]<<endl; 92 } 93 if(dp[1][x]==0) dp[1][x]=1; 94 } 95 ll ans=0; 96 for(int i=0;i<26;++i) 97 { 98 ans+=dp[k][i]; 99 ans%=mod; 100 } 101 printf("%lld ",ans); 102 }