牛客326B 背单词

传送门:https://ac.nowcoder.com/acm/contest/326/B

题意:给你一个n,你需有找有多少个长度从1~n 的单词,满足最长连续元音少于A个并且最长连续辅音长度少于B。

题解:我们定义dp的状态是,dp1[i][j]表示长度为i的,最长连续元音长度为j的单词的个数,

dp2[i][j]表示长度为i的,最长连续辅音长度为j的单词的个数

由于元音的个数为5个可以任意取,辅音的个数为21个可以任意取

转移方程就是dp1[i][j]=(dp1[i][j]+dp1[i-1][j-1])*5,dp2[i][j]=(dp2[i][j]+dp2[i-1][j-1])*21

每次转移完记得更新dp1[i][1] 的状态和dp2[i][1]的状态,即前面全部是元音/辅音,但是后面变成辅音/元音时的个数

计数时记得取模

代码如下:

#include <map>
#include <set>
#include <cmath>
#include <ctime>
#include <stack>
#include <queue>
#include <cstdio>
#include <cctype>
#include <bitset>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <functional>
#define PI acos(-1)
#define eps 1e-8
#define fuck(x) cout<<#x<<" = "<<x<<endl;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define FIN freopen("input.txt","r",stdin);
#define FOUT freopen("output.txt","w+",stdout);
//#pragma comment(linker, "/STACK:102400000,102400000")
using namespace std;
typedef long long LL;
typedef unsigned long long ull;
typedef pair<int, int> PII;
const int maxn = 3e5 + 5;
const LL INF = 1e18 + 7;
const ull mod = 1e9 + 7;
LL gcd(LL a, LL b) {return b ? gcd(b, a % b) : a;}
LL lcm(LL a, LL b) {return a / gcd(a, b) * b;}
LL powmod(LL a, LL b, LL MOD) {LL ans = 1; while (b) {if (b % 2)ans = ans * a % MOD; a = a * a % MOD; b /= 2;} return ans;}
double dpow(double a, LL b) {double ans = 1.0; while (b) {if (b % 2)ans = ans * a; a = a * a; b /= 2;} return ans;}

LL dp1[5005][55];
LL dp2[5005][55];
int main() {
#ifndef ONLINE_JUDGE
    FIN
#endif
    int T;
    scanf("%d", &T);
    while (T--) {
        memset(dp1,0,sizeof(dp1));
        memset(dp2,0,sizeof(dp2));
        int n, a, b;
        cin >> n >> a >> b;
        LL ans = 0;
        dp1[0][0] = 1;
        dp2[0][0] = 1;

        for (int i = 1; i <= n; i++) {
            LL sum1 = 0;
            LL sum2 = 0;
            for (int j = 1; j <= min(a,i); j++) {
                dp1[i][j] = (dp1[i][j] + dp1[i - 1][j - 1] * 5) % mod;
                sum1 = (sum1 + dp1[i - 1][j]) % mod;
            }
            for (int j = 1; j <= min(b,i); j++) {
                dp2[i][j] = (dp2[i][j] + dp2[i - 1][j - 1] * 21) % mod;
                sum2 = (sum2 + dp2[i - 1][j]) % mod;
            }
            dp1[i][1] = (dp1[i][1] + sum2 * 5 % mod) % mod;
            dp2[i][1] = (dp2[i][1] + sum1 * 21 % mod) % mod;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= a; j++) {
                ans = (ans + dp1[i][j]) % mod;
            }
            for (int j = 1; j <= b; j++) {
                ans = (ans + dp2[i][j]) % mod;
            }
        }
        cout << ans << endl;
    }
}
View Code
每一个不曾刷题的日子 都是对生命的辜负 从弱小到强大,需要一段时间的沉淀,就是现在了 ~buerdepepeqi
原文地址:https://www.cnblogs.com/buerdepepeqi/p/10224996.html