题目大意:
已知河两岸的哪两个点之间可以修桥和修这个桥的价值,
桥的高度都是一样的,所以任意两座桥不能交叉。
求在能修最多桥的情况下桥的最大价值。
solution:
按左右端点前后双关键子排序,
在O(n2)LIS的基础上加入权值判断
记F[i]为当前位最长子序列长度,G[i]为价值
如果F[i]<F[j]+1 或 (F[i]=F[j]+1 且 G[i]<G[j]+v[i]))
则F[i]=F[j]+1;G[i]=G[j]+v[i];
//Tvvj1554
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,f[10010],g[10010];
struct Node
{
int u,v,w;
friend bool operator <
(const Node a,const Node b)
{
if(a.u==b.u)return a.v<b.v;
return a.u<b.u;
}
}G[10010];
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;++i)
scanf("%d %d %d",&G[i].u,&G[i].v,&G[i].w);
sort(G+1,G+1+n);
for(int i=1;i<=n;++i)f[i]=1,g[i]=G[i].w;
for(int i=1;i<=n;++i)
for(int j=i-1;j>=1;--j)
{
if(G[i].v<G[j].v)continue;
if(f[i]<f[j]+1 ||(f[i]==f[j]+1 && g[i]<g[j]+G[i].w))
{
f[i]=f[j]+1;
g[i]=g[j]+G[i].w;
}
}
int l=0,res=0;
for(int i=1;i<=n;++i)
{
if(l==f[i] && res<g[i])res=g[i];
if(l<f[i])
{
l=f[i];
res=g[i];
}
}
printf("%d\n",l);
printf("%d\n",res);
return 0;
}