题目链接:
1025 Keep at Most 100 Characters (35分)
思路:
用dp[i][j]
记录字符串从第一个字符到第i
个字符形成的子串、保存j
个字符所形成的sub-sequence
个数;
则我们可以得到递推式
但是这种思想肯定会造成重复的!
记此时char c = s[i]
,则我们需要找到上一次c
出现的位置pos
,减去即可~
代码:
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll mod = 1000000007;
const int maxn = 1005;
const int maxm = 105;
int rcd[30];
ll dp[maxn][maxm];
string s;
void solve(){
s = "0" + s;
int n = s.length() - 1;
for(int i = 1; i <= n; i++){
int pos = rcd[s[i] - 'a'];
dp[i][1] = dp[i - 1][1] + !pos;
for(int j = 2; j < maxm; j++){
dp[i][j] = (dp[i - 1][j] + dp[i - 1][j - 1] - (pos ? dp[pos - 1][j - 1] : 0) + mod) % mod;
}
rcd[s[i] - 'a'] = i;
}
ll ans = 0;
for(int i = 1; i <= 100; i++) ans = (ans + dp[n][i]) % mod;
cout << ans;
}
int main(){
#ifdef LOCAL
freopen("Sakura.txt", "r", stdin);
#endif
cin >> s;
solve();
return 0;
}