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; }