Codeforces Round #210 (Div. 1) problem C Levko and Strings

来源:互联网 发布:蒋中正 知乎 编辑:程序博客网 时间:2024/04/28 00:36

http://codeforces.com/contest/360/problem/C

极好的一道动态规划, 给定一个小写字母的字符串 S, 求其相同长度的串T,T中恰包含K个子串字典序大于S中相同位置的子串,求T有几种,记 DP[ i ] [ j ][ 0或1 ] 为 第i个位置为止已有J个子串字典序大于S中相对应为止的子串,最后一维表示相同与否,我在这里用0表示相同,及T[i]=s[i],否则T[i]!=s[i]   我固定位置i, 向前遍历 当到达位置t时, 令 (S[t] = T[t] ,S[t+1] = T[t+1]) S[i] 与T[i] 的关系分别讨论。此时

若T[i]>S[i], t 每向前移动一位 , 满足条件的子串就增加 n-i+1 个,我们若枚举 j,则只需枚举 j/(n-i+1) 次,整体复杂度为n*n*log(n)

#include<iostream>#include<cstdio>#include<cmath>#include<cstring>#include<algorithm>#include<queue>#include<set>#include<cstring>#include<vector>#include<bitset>#include<iterator>#include<list>#include<map>#include<cstdlib>#include<ctime>#include<utility>using namespace std;#define L p->ch[0]#define R p->ch[1]#define KeyTree root->ch[1]->ch[0]typedef long long LL;typedef pair<char, int> PII;typedef vector<int> VI;const int maxn = 2111;const int INF = 1 << 30;const int mod = (int) (1e9 + 7);const LL X = 123;template<typename T>T gcd(T a, T b) {return b ? gcd(b, a % b) : a;}LL dp[maxn][maxn][2];char s[maxn];int ch[maxn];LL P[maxn];int main() {ios::sync_with_stdio(false);int n, k, i, j, t, r;cin >> n >> k;cin >> (s + 1);dp[0][0][1] = 1;dp[0][0][0] = 0;P[0] = 1;for (i = 1; i <= n; ++i) {ch[i] = (s[i] ^ 0x60);}r = n;for (i = 1, r = n; i <= n; ++i, --r) {for (j = 0; j <= k; ++j) {dp[i][j][0] = dp[i][j][1] = dp[i - 1][j][0] + dp[i - 1][j][1];LL& tv = dp[i][j][1];tv = dp[i][j][1] * (ch[i] - 1) % mod;for (t = i - 1; t >= 0 && j - (i - t) * r >= 0; --t) {tv += (dp[t][j - (i - t) * r][1]) * (26 - ch[i]);}tv %= mod;}}LL ans = (dp[n][k][0] + dp[n][k][1]) % mod;cout << ans << endl;return 0;}


原创粉丝点击