abc179d
大意
给定 (N) 和 (K) 个互不相交的整数端点区间 ([L_i, R_i]) , 定义 (S = cup_i[L_i,R_i]capmathbb{N}) 。
初始站在台阶1,可以选择 (iin S) 并走到第 (1+i) 阶。
问,走到第 (N) 阶的方法数有多少种。
思路
很像那个dp入门题...
但是有一些点无法转移到当前点 (k) ,因为 (S) 可能并不包含 (1...k-1) 所有的数...
考虑区间对当前点的贡献,显然,当 (k) 变为 (k+1) 区间贡献的改变最多只有首末的值。
枚举区间计算贡献,然后更新。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cmath>
#include <cstring>
using namespace std;
#define ll long long
#define ull unsigned long long
#define cint const int&
#define Pi acos(-1)
const int mod = 998244353;
const int inf_int = 0x7fffffff;
const ll inf_ll = 0x7fffffffffffffff;
const double ept = 1e-9;
int n, k;
int l[11], r[11];
ll sum[11];
ll dp[200200];
int main() {
cin >> n >> k;
for(int i=1; i<=k; i++) cin >> l[i] >> r[i];
dp[1] = 1;
for(int i=2; i<=n; i++) {
for(int j=1; j<=k; j++) {
if(l[j] < i) {
sum[j] += dp[i-l[j]];
if(r[j] < i-1) sum[j] -= dp[i-r[j]-1];
if(sum[j] < 0) sum[j] += mod;
else sum[j] %= mod;
dp[i] += sum[j];
dp[i] %= mod;
}
}
}
cout << dp[n];
return 0;
}