ARC065F

fi,j 表示前 i 个位置使用 j1 的方案数。

转移很简单:fi,j=fi1,j+fi1,j1

但是有些状态是非法的,所以对于每个 i 求出其前缀可以操作的最右的位置 Ri,以及 prei 表示前缀 1 的数量。

于是 1 的数量 [max(0,i(RipreRi)),min(i,preRi)]

时间复杂度 O(n2)

Code:

#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 3005, mod = 1e9 + 7;
int n, m;
char s[N];
int pre[N], R[N];
int f[N][N];

void add(int &a, int b) {
	a += b;
	if (a >= mod) a -= mod; 
}

int main() {
	scanf("%d%d%s", &n, &m, s + 1);
	for (int i = 1; i <= n; ++i) pre[i] = pre[i - 1] + (s[i] - '0'), R[i] = i;
	for (int i = 1, l, r; i <= m; ++i) scanf("%d%d", &l, &r), R[l] = max(R[l], r);
	for (int i = 1; i <= n; ++i) R[i] = max(R[i], R[i - 1]);
	f[0][0] = 1;
	for (int i = 1; i <= n; ++i) {
		int mx = min(i, pre[R[i]]), mn = max(0, i - (R[i] - pre[R[i]]));
		for (int j = mn; j <= mx; ++j) {
			add(f[i][j], f[i - 1][j]);
			if (j) add(f[i][j], f[i - 1][j - 1]);
		}
	}
	printf("%d", f[n][pre[n]]);
	return 0;
}
posted @   Kobe303  阅读(27)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
点击右上角即可分享
微信分享提示