zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    Hibernate框架学习(二)——api详解
    Hibernate框架学习(一)——入门
    事务(二)——事务的特性和隔离级别
    事务(一)
    MySQL ------ 使用正则表达式进行搜索 regexp (八)
    MySQL ---- 过滤数据 通配符 like (七)
    Java --------- I/O(七) 序列化
    MySQL ------ 过滤数据 and、or、in、not(七)
    MySQL ------ 过滤数据 where 子句(六)
    MySQL ------ 排序检索(五)
  • 原文地址:https://www.cnblogs.com/liuweimingcprogram/p/6378068.html
Copyright © 2011-2022 走看看