选择之间唯一的矛盾在于时间的冲突,把所有区间右端点+R,sort并处理出选择当前区间之后可以选的最近的下一个区间。
dp[i]表示考虑第i个区间以后能得到的最大值。从右往左转移即可。
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; const int maxn = 1e3+5; struct Seg { int l,r,v; bool operator < (const Seg& th) const{ return l < th.l ;//|| (l == rh.l && r < rh.r) ; } void IN(){ scanf("%d%d%d",&l,&r,&v); } }seg[maxn]; int nxt[maxn]; int dp[maxn]; int n,m,R; void sol() { sort(seg,seg+m); seg[m].l = 1<<30;//便于处理 for(int i = 0; i < m; i++){ int j = i+1; while(seg[j].l < seg[i].r) j++; //我试过二分,结果更慢 nxt[i] = j; } for(int i = m; i--;){ dp[i] = max(dp[i+1],dp[nxt[i]]+seg[i].v); } printf("%d ",dp[0]); } //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif scanf("%d%d%d",&n,&m,&R); for(int i = 0; i < m; i++){ seg[i].IN(); seg[i].r += R; } sol(); return 0; }