最长上升子序列 HDU 1025 Constructing Roads In JGShining's Kingdom

最长上升子序列o(nlongn)写法

dp[1]=a[1];
int len=1;
for(int i=1;i<=n;i++){
    if(a[i]>dp[len]) dp[++len]=a[i];
    else *upper_bound(dp+1,dp+1+len,a[i])=a[i];
}

数组dp[len]描述的是长度为len时的结尾的最小元素。

怎么样才能不交叉呢?i和j相连,i1和j1想连,只有i<i1&&j<j1时才不会交叉,所以让第行单调递增,然后第而行求他的LIS

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=5E5+7;
const int INF=1E9+7;
struct stu{
    int a,b;
    bool friend operator <(const stu x,const stu y){
        return x.a<y.a;
    }
}arr[N];
int a[N],dp[N];
int main(){
    ios::sync_with_stdio(0);
    int n;
    int t=0;
    while(cin>>n){
        for(int i=1;i<=n;i++) cin>>arr[i].a>>arr[i].b;
        sort(arr+1,arr+1+n);
        for(int i=1;i<=n;i++){
            a[i]=arr[i].b;
        }
        dp[1]=a[1];
        int len=1;
        for(int i=1;i<=n;i++){
            if(a[i]>dp[len]) dp[++len]=a[i];
            else *upper_bound(dp+1,dp+1+len,a[i])=a[i];
        }
        cout << "Case " << ++t << ":\n";
        cout << "My king, at most " << len << (len > 1 ? " roads" : " road") << " can be built.\n\n";
    }
    return 0;
}

注:sb了。为什么要用struct呢?还得排序,,,直接a[x]=y就行.....

猜你喜欢

转载自www.cnblogs.com/Accepting/p/12410110.html