思路:
dp
dp[i]表示构成i的区间的右端点
先将询问按r排序
然后,对于每次询问,每次枚举 i 从 n-x 到 1,如果dp[i] >= l , 那么 dp[i+x] = max(dp[i+x], dp[j])
#include<bits/stdc++.h> using namespace std; #define fi first #define se second #define pi acos(-1.0) #define LL long long //#define mp make_pair #define pb push_back #define ls rt<<1, l, m #define rs rt<<1|1, m+1, r #define ULL unsigned LL #define pll pair<LL, LL> #define pii pair<int, int> #define mem(a, b) memset(a, b, sizeof(a)) #define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0); #define fopen freopen("in.txt", "r", stdin);freopen("out.txt", "w", stout); //head const int N = 1e4 + 5; struct node { int l, r, x; bool operator < (const node & t) const { return r < t.r; } }Q[N]; int dp[N]; int main() { int n, q, l, r, x; scanf("%d%d", &n, &q); for (int i = 1; i <= q; i++) { scanf("%d%d%d", &Q[i].l, &Q[i].r, &Q[i].x); } sort(Q+1, Q+1+q); for (int i = 1; i <= q; i++) { l = Q[i].l; r = Q[i].r; x = Q[i].x; for (int j = n-x; j >= 1; j--) { if(dp[j] >= l) dp[j+x] = max(dp[j+x], dp[j]); } dp[x] = r; } int ans = 0; for (int i = 1; i <= n; i++) ans += (dp[i]>0); printf("%d ", ans); for (int i = 1; i <= n; i++) if(dp[i]) printf("%d ", i); return 0; }