中文题
想法:
首先状态的设定很容易想
f[i] 代表第 i 时刻可获得的最大空暇时间
但是状态转移的时候我们发现 如果正向转移,f[i] 会受到后面选择的i以及它的持续时间的影响,所以不可以正向转移
那么我们考虑倒着转移
f[i] = f[i+1] + 1 (当前时刻无任务)
f[i] = max{f[i],f[i+p[i].ed]} (当前时刻有任务)
#include <algorithm> #include <string> #include <string.h> #include <vector> #include <map> #include <stack> #include <set> #include <queue> #include <math.h> #include <cstdio> #include <iomanip> #include <time.h> #include <bitset> #include <cmath> #include <sstream> #include <iostream> #include <cstring> #define LL long long #define ls nod<<1 #define rs (nod<<1)+1 #define pii pair<int,int> #define mp make_pair #define pb push_back #define INF 0x3f3f3f3f const double eps = 1e-10; const int maxn = 1e4 + 10; const LL mod = 1e9 + 7; int sgn(double a){return a < -eps ? -1 : a < eps ? 0 : 1;} using namespace std; struct node { LL st,ed; }p[maxn]; bool cmp (node a,node b) { return a.st > b.st; } LL f[maxn],vis[maxn]; int main() { //freopen("../in.txt","r",stdin); int n,k; scanf("%d%d",&n,&k); for (int i = 1;i <= k;i++) { scanf("%lld%lld",&p[i].st,&p[i].ed); vis[p[i].st]++; } sort(p+1,p+1+k,cmp); int cnt = 1; for (int i = n;i >= 1;i--) { if (!vis[i]) f[i] = f[i+1] + 1; else { for (int j = 1;j <= vis[i];j++) { f[i] = max(f[i],f[i+p[cnt].ed]); cnt++; } } } printf("%lld ",f[1]); return 0; }