HDU 1800 Flying to the Mars(Trie字典树 upper_bound)

题意:有一个序列 要组成多个子序列

        每个子序列必须单调递增

        问最少组成多少个子序列

思路1: 因为严格递增 所以每个数只能在一个子序列中出现一次 出现次数最多的数的次数就是答案

           运用 upper_bound(a,a+n,a[i])-lower_bound(a,a+n,a[i]) 求出 

         (由于数据较水 并没有达到30位)      

 

         upper_bound(begin,end,key),start是查找的起点,end是终点,key是关键值,lower_bound()用法一 样,

         upper_bound()函数,返回第一个大于要找的值得位置(或者理解是这个元素的下一个位置),

         而Lower_bound是小于等于关键字的位 置(或者理解为关键字第一次出现 的位置),

#include<stdio.h>

#include<string.h>

#include<math.h>

#include<iostream>

#include<algorithm>

#include<queue>

#include<stack>

#define mem(a,b) memset(a,b,sizeof(a))

#define ll __int64

#define MAXN 1000

#define INF 0x7ffffff

#define lson l,m,rt<<1

#define rson m+1,r,rt<<1|1

using namespace std;

int a[5000];

int main()

{

    int i,j,n;

    while(scanf("%d",&n)!=EOF)

    {

        for(i=0; i<n; i++)

            scanf("%d",&a[i]);

        sort(a,a+n);

        int cnt;

        int maxx=0;

        for(i=0; i<n; i++)

        {

            cnt=(upper_bound(a,a+n,a[i])-lower_bound(a,a+n,a[i]));



            if(cnt>maxx) maxx=cnt;

        }

        printf("%d\n",maxx);

    }

    return 0;

}

 

思路2:

         当数据达到30位时

         就需要运用字典树记录每个数出现的次数

         

#include<cstdio>

#include<cstring>

#include<iostream>

#include<algorithm>

using namespace std;

int  ch[30000+100][20];

int val[30000+10];

int sz;   //节点总数

int idx(char c) {return c-'0';}

int ans;



void insert(char *s)

{

    int u=0,n=strlen(s);

    for(int i=0;i<n;i++)

    {

        int c=idx(s[i]);

        if(!ch[u][c])    //节点不存在

        {

            memset(ch[sz],0,sizeof(ch[sz]));

            ch[u][c]=sz++;            //新建节点

        }

        u=ch[u][c];// [上一个数的编号][这个数为c]

    }

    val[u]++;                     //字符串的最后一个字符的附加信息

    if(val[u]>ans) ans=val[u];

}

int main()

{

    int n,i,j,k;

    char s[3000+100];

    while(scanf("%d",&n)!=EOF)

    {

        sz=1;    //初始时只有一个根节点

        memset(ch[0],0,sizeof(ch[0]));

        memset(val,0,sizeof(val));

        ans=1;

        for(i=0;i<n;i++)

        {

            scanf("%s",s);

            j=0;

            while(s[j]=='0') j++;

            insert(s+j);

        }

        printf("%d\n",ans);

    }

    return 0;

}

  

 

你可能感兴趣的:(trie)