题意 有m个区间,区间有一个权重,区间间有交叉,问你怎么选择区间让权重之和最大
思路 这题递推时,主要要想到,如果新的区间和之前选好的那个区间有交叉,那么去掉已选好区间最后面的那个区间,新的区间一定可以放进去。
dp[i]表示前i个区间,第i个区间一定放入的最大权值和。
先按开始时间进行排序。
当start[i] >= end[j]时,dp[i] = max(dp[i],dp[j]+value[i]) , 0<=j<i
最后结果取max就行了。
这题复杂度其实还可以再降到O(mlogm),以后还要再练习~
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxm = 1005;
int dp[maxm];
int n,m,r;
struct Node{
int s,e,v;
}node[maxm];
bool cmp(Node x,Node y)
{
return x.s < y.s || x.s == y.s && x.e< y.e;
}
int main()
{
scanf("%d%d%d",&n,&m,&r);
int i,j;
for(i=1;i<=m;i++)
{
scanf("%d%d%d",&node[i].s,&node[i].e,&node[i].v);
node[i].e += r;
}
sort(node,node+m+1,cmp);
for(i=1;i<=m;i++)
{
for(j=0;j<i;j++)
{
if(node[i].s >= node[j].e)
dp[i] = max(dp[i],dp[j]+node[i].v);
}
}
int ans = 0;
for(i=1;i<=m;i++)
ans = max(ans,dp[i]);
cout<<ans<<endl;
return 0;
}