这个题虽然知道是dp,但是刚刚开始,思路尚不明确。
1.首先,这个题应该是从后往前推。因为如果你选择了一项任务,你现在的状态是从未来的时刻转移回来的。换句话说,你不能在这个时刻选择这个时刻已经结束的工作。因此,应该从后往前推。
2.如果从后往前推,那么就需要已知初始时刻在dp[n]的值。所以,让dp[i]代表从i~n中间的空余时间。dp[n]=0
3.其余的,例如线段覆盖的排序问题用结构体写并排序,用一个mis_now储存此时的任务个数,用num储存已经遍历到的任务个数(因为已经排序,所以遍历也是从rw数组1~k遍历)。细节问题
#include<bits/stdc++.h>
#define mxn 10005
using namespace std;
int dp[mxn]={0},mis_now[mxn]={0};
struct mis{
int ks,js;
};
mis rw[mxn];
bool cmp(mis a,mis b){
if(a.ks!=b.ks){
return a.ks>b.ks;
}
else{
return a.js>b.js;
}
}
int main(void){
int n,k;
cin>>n>>k;
for(int i=1;i<=k;i++){
int st,en;
cin>>st>>en;
rw[i].ks=st;
rw[i].js=st+en;
mis_now[st]++;
}
sort(rw+1,rw+k+1,cmp);
int num=1;
for(int i=n;i>=1;i--){
if(!mis_now[i]){
dp[i]=max(dp[i],dp[i+1]+1);
}
else{
for(int j=1;j<=mis_now[i];j++){
dp[i]=max(dp[i],dp[rw[num++].js]);
}
}
}
printf("%d",dp[1]);
}