code3027 线段覆盖2

dp

数据:d[i].a d[i].b d[i].v 分别表示第i条线段的起始点,结束点,价值

先按d[i].b排好序

dp[i]表示前i条线段的最大价值

方程:

dp[i]=max{ dp[i-1]

       d[i].v

       dp[p]+d[i].v  p<i,d[p].b<=d[i].a AND p最大

      }

这三种情况分别对应着:不放i,只放i,放前p个和i

因为dp是递增的,所以取满足d[p].b<=d[i].a(能放i)的最大的p即可

代码如下:

#include<iostream>
#include<algorithm>
#define Size 1005
using namespace std;

int n;
int dp[Size]; 
struct L{
    int a,b,v;
}d[Size];

bool cnt(L x,L y){
    return x.b<y.b; //b小的在前面,b一样随便 
}

int main(){
    cin>>n;
    int x,y,v;
    for(int i=1;i<=n;i++){
        cin>>x>>y>>v;
        if(x>y)swap(x,y);
        d[i].a=x;
        d[i].b=y;
        d[i].v=v;
    } 
    
    sort(d+1,d+1+n,cnt);
    
    dp[0]=0;
    for(int i=1;i<=n;i++){
        dp[i]=max(dp[i-1],d[i].v);
        for(int p=i-1;p>0;p--){
            if(d[p].b<=d[i].a){
                dp[i]=max(dp[i],dp[p]+d[i].v);
                break;
            }
        }
        //cout<<dp[i]<<endl;
    }
    
    cout<<dp[n]<<endl;
    
    fclose(stdin);
    return 0;
}
原文地址:https://www.cnblogs.com/FuTaimeng/p/5525284.html