题目链接: 题目地址
题意:一个数轴上有2n个点,你需要把这个2n个点用n个线段配对
n个线段配对后需要有两种关系之一: (1) 两线段长度相等 (2)一个线段包含另一个线段
问有x条线段时,有多少种配对方式
首先思考
-
若两线段长度相等:对于x条线段,配对2x个点, 若x为6,则有4种配对方案,分别是每条线段长度为(1,2,3,6) 。 可以画图理解一下, 这样我们可以发现dp[x] 有一方面贡献 可以+ x的因子个数
-
再思考一个线段包含另一条线段的情况,对于x条线段,我们可以思考发现,这种包含情况最多只有一个“团”, 意思也就是说,它们这些是连在一块的,没有单独成为多个独立的部分。
考虑多个拱交叉的情况,他们的合法部分是多个拱的公共部分的dp值 所有,对于对于dp[x] 的贡献一部分来自于 i:1 ~ x-1 的dp[i] 累加值。 (为什么i不到x呢? i若等于了x,就没有了公共区间,回到了1的情况)
所以 dp[x] = (累加)dp[1~x-1] + x的因子个数
AC代码:
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <map> using namespace std; //------------------------ const int N = 1e6 + 10,mod = 998244353; typedef long long ll; ll f[N]; ll num[N]; int main() { int n; cin>>n; for(int i=1;i<N;i++){ for(int j=i;j<N;j=j+i){ num[j] =(num[j]+1)%mod; } } ll pre = 0; f[1]=1; f[2]=3; pre = 4; for(int i=3;i<=n;i++){ f[i] = (f[i]+num[i]+pre)%mod; pre =(pre+f[i])%mod; } cout<<f[n]<<endl; return 0; }