hdu 1025 Constructing Roads In JGShining's Kingdom(最长上升子序列)

题意:贫穷和富有的城市都按顺序1-n排列,需要在中间建造尽可能多的道路,最多可以建造多少条?

解:如果条件这样给出,贫穷的城市按顺序排列,并且按顺序给出每个贫穷城市需要的资源,那么能建造的最多的道路数就是这个顺序中的最长上升子序列的长度。

#include <algorithm>
#include <iostream>
#include <cstring>
#include <cstdio>
#include <vector>
#include <cmath>
#include <queue>
#include <deque>
#include <map>

using namespace std;
typedef long long ll;

const int maxn=1e5+10;

ll n,a[maxn];
ll dp[maxn];

ll lower_bound(ll *a,int x,int y,ll v){
    int m;
    while(x<y){
        m=x+(y-x)/2;
        if(a[m]>=v)y=m;
        else x=m+1;
    }
    return x;
}

ll q[maxn],r[maxn];

int main(){
    int o=1;
    while(scanf("%lld",&n)!=EOF){
        for(int i=0;i<n;i++){
            scanf("%lld%lld",&q[i],&r[i]);
        }
        for(int i=0;i<n;i++){
            a[q[i]-1]=r[i]-1;
        }
        int m=0;
        for(int i=0;i<n;i++){
            if(m==0||dp[m-1]<a[i]){
                dp[m++]=a[i];
            }else{
                ll j=lower_bound(dp,0,m,a[i]);
                dp[j]=a[i];
            }
            /*验证正确性
            for(int j=0;j<m;j++){
                printf("%lld ",dp[j]);
            }printf("\n");
            */
        }
        printf("Case %d:\n",o++);
        printf("My king, at most %d road",m);
        if(m>1)printf("s");
        printf(" can be built.\n\n");

    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/wz-archer/p/12349723.html