传送门: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; } }