ARC074E
设 fi,j,k 表示从 i 往前,第一个与 ai 颜色不同的位置是 j,第一个颜色与 ai,aj 都不相同的位置是 k 的方案数,其中某个值为 0 表示这个位置不存在。当然 i>j>k(特别地,当 j=0 时 k 可以为 0)
如果我们有一个形如 (l,r,x) 的限制,那么这样的三元组 (i,j,k)(r=i) 是不符合限制的(即 fi,j,k 需要设为 0):
-
x=1 且 l≤j,因为 [l,r] 这段区间内出现了一个与 ai 不同的 aj。
-
x=2 且 l≤k 或 j<l,前者是因为出现了第三种既不同于 ai 也不同于 aj 的颜色,后者是因为距离 i 最近的不同于 ai 的 aj 并不在 [l,r] 内,即 [l,r] 这段区间内只有一个颜色。
-
x=3 且 k<l,因为距离 i 最近的第三种不同的颜色 ak 在 [l,r] 之外,即 [l,r] 内至多只有两种颜色。
所以用 n 个 vector
来保存限制,每次到一个位置把以它为右端点的限制取出然后剔除不合法的状态。
考虑从 i 转移 到 i+1:
- 若 ai+1=ai,则 fi+1,j,k←fi+1,j,k+fi,j,k。
- 若 ai+1=aj,则 fi+1,i,k←fi+1,i,k+fi,j,k。
- 若 ai+1=ak,则 fi+1,i,j←fi+1,i,j+fi,j,k。
初值为 f1,0,0=3,因为这里的 DP 只考虑颜色相对之间的关系,而 a1 有三种选法,确定了 a1 之后,所有合法的方案都被不重不漏的划分了。
最终答案就是所有 fn,j,k 的和,其中 j<n,k<max(1,j)。
时间复杂度 O(n3)。
Code:
#include <bits/stdc++.h>
using namespace std;
#define fi first
#define se second
typedef pair <int, int> pii;
typedef long long ll;
const int N = 305, mod = 1e9 + 7;
int n, m;
vector <pii> vec[N];
int f[N][N][N];
void add(int &a, int b) {
a += b;
if (a >= mod) a -= mod;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 1, l, r, cnt; i <= m; ++i) scanf("%d%d%d", &l, &r, &cnt), vec[r].emplace_back(l, cnt);
f[1][0][0] = 3;
for (int i = 0; i <= n; ++i) {
for (auto it : vec[i]) {
int l = it.fi, cnt = it.se;
for (int j = 0; j < i; ++j) {
int lim = j ? j - 1 : 0;
for (int k = 0; k <= lim; ++k) {
if (cnt == 1 && l <= j) f[i][j][k] = 0;
if (cnt == 2 && (l <= k || j < l)) f[i][j][k] = 0;
if (cnt == 3 && k < l) f[i][j][k] = 0;
}
}
}
if (i == n) break;
for (int j = 0; j < i; ++j) {
int lim = j ? j - 1 : 0;
for (int k = 0; k <= lim; ++k) {
if (!f[i][j][k]) continue;
add(f[i + 1][j][k], f[i][j][k]), add(f[i + 1][i][k], f[i][j][k]), add(f[i + 1][i][j], f[i][j][k]);
}
}
}
int ans = 0;
for (int j = 0; j < n; ++j) {
int lim = j ? j - 1 : 0;
for (int k = 0; k <= lim; ++k)
add(ans, f[n][j][k]);
}
printf("%d", ans);
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话