题目描述
输入`N`,`K`给你`K`个区间L_k到R_k
从`k`个区间中可以得到一个集合S中包含所有区间的交集
我们可以无限次使用区间的数 问有多少中方法从1 变成 N样例
5 2
1 1
3 4S为{1,3,4};
1. 1→2→3→4→5
2. 1→2→5
3. 1→4→5
4. 1→5所以答案为4.
前缀和维护DP
TLE思想:将每个区间的数都求出来 $f[j]$ 表示从1到j的方法数
易得转移方程为:
f[j] += f[j-v[i]]
正解:我每次得到的j的转移数都依赖于前i个区间
我们可以发现,第i 个点的答案为前i 个1 − i 区间答案的累加,而现在我们只知道有k个区间可以利用,同理我们类别1 − i 的方式取,可用区间的元素来构造答案即可。
#include <bits/stdc++.h>
//#define x first
//#define y second
using namespace std;
const int mod = 998244353, maxn = 300010;
typedef pair<int, int>PII;
typedef long long LL;
// The desire of his soul is the prophecy of his fate
int L[15], R[15];
LL sum[maxn];
LL dp[maxn];
int main()
{
LL n, k;
cin >> n >> k;
for (int i = 1; i <= k; i++)
cin >> L[i] >> R[i];
dp[1] = 1;
sum[1] = 1;
for (int i = 2; i <= n; i++)
{
for (int j = 1; j <= k; j++)
{
int l = L[j], r = R[j];
dp[i] = (dp[i] + sum[max(0, i - l)] - sum[max(0, i - r - 1)] + mod) % mod;
}
sum[i] = (sum[i - 1] + dp[i]) % mod;
}
cout << dp[n] % mod;
return 0;
}
总结:TLE了好久 没考虑的区间之间的依赖关系 一开始就把所有的区间数都求出来n^2肯定超了
前缀和用来维护这中每个数是在一个区间的关系的DP很好用!!!