ARC065F
设 fi,j 表示前 i 个位置使用 j 个 1 的方案数。
转移很简单:fi,j=fi−1,j+fi−1,j−1
但是有些状态是非法的,所以对于每个 i 求出其前缀可以操作的最右的位置 Ri,以及 prei 表示前缀 1 的数量。
于是 1 的数量 ∈[max(0,i−(Ri−preRi)),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;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具