C. Mahmoud and a Message dp + 暴力

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

 

关键在于dp,如何计数。

设dp[i]表示前i个字母中,能分成多少份合法的情况。那么答案就是dp[n],其中dp[0] = 1;

比如说:aab的,也就是样例。

对于每一个i,枚举其往后能组合成那个,比如b,能组合成b,也就是自己一个,或者ab,但是不能aab,因为违反了条件。

那么,组合成b的时候,就应该加上dp[2]的值,也就是前2个分成的合法情况有多少种,b作为单独一个插去后面。

ab同理。

dp[1] = 1,也就是只有a,

dp[2] = 2,有a/a  和 aa

dp[3] = 3,有a/a/b、aa/b和a/ab

 

#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <assert.h>
#define IOS ios::sync_with_stdio(false)
using namespace std;
#define inf (0x3f3f3f3f)
typedef long long int LL;


#include <iostream>
#include <sstream>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <string>
#include <bitset>

const int MOD = 1e9 + 7;
const int maxn = 1e3 + 20;
int cnt[maxn][26 + 2];
char str[maxn];
int a[maxn];
int dp[maxn];
bool check(int last, int pre) {
    for (int i = 1; i <= 26; ++i) {
        if (cnt[last][i] - cnt[pre - 1][i] != 0 && last - pre + 1 > a[i]) return false;
    }
    return true;
}
void work() {
    int n;
    cin >> n;
    cin >> str + 1;
    for (int i = 1; i <= 26; ++i) cin >> a[i];
    for (int i = 1; i <= n; ++i) {
        for (int j = 1; j <= 26; ++j) {
            if (str[i] - 'a' + 1 == j) {
                cnt[i][j] = cnt[i - 1][j] + 1;
            } else cnt[i][j] = cnt[i - 1][j];
        }
    }
    int ansone = 0, anstwo = -inf;
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j >= 1; --j) {
            if (check(i, j)) {
                anstwo = max(anstwo, i - j + 1);
            } else break;
        }
    }
    int ansthree = 1;
    int pre = 1;
    for (int i = 1; i <= n; ++i) {
        if (check(i, pre) == false) {
            ansthree++;
            pre = i;
        }
    }
    dp[0] = 1;
    for (int i = 1; i <= n; ++i) {
        for (int j = i; j >= 1; --j) {
            if (!check(i, j)) break;
            dp[i] += dp[j - 1];
            dp[i] %= MOD;
        }
    }
//    for (int i = 1; i <= n; ++i) {
//        cout << dp[i] << endl;
//        ansone += dp[i];
//        ansone %= MOD;
//    }
//    ansone = (ansone + MOD - n + 1) % MOD;
    cout << dp[n] << endl;
    cout << anstwo << endl;
    cout << ansthree << endl;
}
int main() {
#ifdef local
    freopen("data.txt", "r", stdin);
//    freopen("data.txt", "w", stdout);
#endif
    IOS;
    work();
    return 0;
}
View Code

 

posted on 2017-02-08 14:34  stupid_one  阅读(118)  评论(0编辑  收藏  举报

导航