[ABC217F] Make Pair 题解
[ABC217F] Make Pair 题解
思路解析
通过
接下来是重点,就是遍历每一个
这体现了一个区间
这种情况下可能出现的方案有:【1,2,3,4】,【2,1,3,4】,【1,3,4,2】……
这种情况下的方案则和上一种情况一模一样,原因则是因为我们没有给
最后就是由于是算方案数,就说明区间
左边的 1,2,3 代表区间
这里不放出 a,b 是因为合并后原来一个方案中的相对顺序不会改变,画出横线是为了更好理解其实这就是一个在横线中填入相对顺序有序数字的一个问题,其实这个例子的方案数就是
时间复杂度:三层区间 dp,每层最大都是
code
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 1010;
const ll mod = 998244353;
ll n, m, f[N][N], c[N][N];
bool frd[N][N];
int main() {
cin >> n >> m;
n *= 2ll;
for(int i = 1, a, b; i <= m; i++) {
cin >> a >> b;
frd[a][b] = frd[b][a] = true; //标记为朋友
}
for(int i = 1; i <= n; i++) f[i + 1][i] = 1;
c[0][0] = 1;
for(int i = 1; i <= n; i++) {
for(int j = 1; j <= i; j++) {
c[i][j] = (c[i - 1][j - 1] + c[i - 1][j]) % mod; //预处理组合数
}
}
for(int i = 2; i <= n; i += 2) {
for(int l = 1, r = l + i - 1; l + i - 1 <= n; l++, r++) {
if(frd[l][r]) f[l][r] = f[l + 1][r - 1]; //小特判
for(int k = l + 1; k <= r - 1; k += 2) {
int l1 = (k - l + 1) / 2, l2 = (r - k) / 2;
if(frd[l][k]) { //去重的关键
f[l][r] = (f[l][r] + ((f[l + 1][k - 1] * f[k + 1][r]) % mod * c[i / 2 + 1][l1 + 1]) % mod) % mod; //注意要乘上组合数
}
}
}
}
cout << f[1][n];
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】