Solution - CF909C

传送门

Solution.#

很显然的一道 DP 。

定义状态 dpi,j 为在第 i 行有 j 个换行的方案数。

假设第 i1 行为 f ,那么第 i 行就必须多一个换行,所以 dpi,j=dpi1,j1

否则第 i1 行为 s ,此时不难推出第 i 行换行个数的范围是 ji2 ,则 dpi,j=k=ji2dpi1,k

此时时间复杂度为 O(n3) ,还不够优秀。

我们可以注意到 k=ji2dpi1,k 可以用前缀和来维护。这样复杂度就降为 O(n2)

Code.#



#include <bits/stdc++.h>
#define int long long
using namespace std;
template <typename T>
void read(T &x) {
	x = 0; T f = 1;
	char c;
	c = getchar();
	while (c < '0' || c > '9') {
		if (c == '-') f = -1;
		c = getchar();
	}
	while (c >= '0' && c <= '9') {
		x = (x << 1) + (x << 3) + c - '0';
		c = getchar();
	}
	x *= f;
} 

const int MOD = 1e9 + 7;
char a[5005];
int dp[5005][5005];
int sum[5005];
int n;
signed main() {
	read(n);
	for (int i = 1; i <= n; i++) {
		cin >> a[i];
	}
	dp[1][0] = 1;
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= i; j++) {
			if (a[i - 1] == 'f') dp[i][j] = dp[i - 1][j - 1] % MOD;
			else {
				dp[i][j] = (dp[i][j] + sum[i - 2] - sum[j - 1] + MOD) % MOD;
			}
		}
		for (int j = 0; j <= i; j++) {
			sum[j] = (sum[j - 1] + dp[i][j]) % MOD;
		}
	}
	int ans = 0;
	for (int i = 0; i <= n; i++) {
		ans = (ans + dp[n][i]) % MOD;
	}
	printf("%lld", ans);
	return 0;
}
posted @   cqbzjyh  阅读(52)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 因为Apifox不支持离线,我果断选择了Apipost!
· 通过 API 将Deepseek响应流式内容输出到前端
点击右上角即可分享
微信分享提示
主题色彩