HDU 2227 Find the nondecreasing subsequences

来源:互联网 发布:淘宝买家订单怎么导出 编辑:程序博客网 时间:2024/06/07 00:56

题目链接~~>

做题感悟:开始想到用 2^n 这样来求子序列但是这样会多算很多(因为你不知道前面比它小的数的顺序是怎样的),很纠结看解题报告+自己理解用了一个晚上可怜

解题思路:注意:这题如果出现 1 1 1 结果也是 7,并不是 3 。这题需要用到DP 的思想,假设dp[ i ]  为 i 时a[i] 所形成的不递减子序列,那么dp[ i ]  =  sum ( dp[ j ] ) +1 ( j < i &&   a[ i ] > a[ j ] ) 即:小于a[ i ] 且在 i 前面的所形成的子序列的和。但是这样是不行的 0< n < 100000 如果这样做必定超时。其实仔细观察一下,这要做和求逆序数差不多,向上更新,向下查询,于是要用到树状数组,但是 0 < ai < 2^31 这么大的数肿么办??? 离散化(具体见代码)。

代码:

#include<stdio.h>#include<iostream>#include<map>#include<stack>#include<string>#include<string.h>#include<stdlib.h>#include<math.h>#include<vector>#include<queue>#include<algorithm>using namespace std ;#define LEN sizeof(struct node)#define lld __int64const double PI = 3.1415926535898 ;const int INF = 99999999 ;const double esp = 1e-8 ;const lld  mod= 1000000007 ;const lld MX = 100005 ;int n ;int c[MX],b[MX] ;struct node{    int x,y ;}T[MX] ;bool cmp(node a,node b){    return  a.x < b.x ;}int lowbit(int x){    return x&(-x) ;}int get_su(int x) // 求和{    int ans=0 ;    while(x>0)    {        ans=(ans+c[x])%mod ;        x-=lowbit(x) ;    }    return ans ;}void update(int x,int nx)//更新{    while(x<=n)    {        c[x]=(c[x]+nx)%mod ;        x+=lowbit(x) ;    }}int main(){    while(~scanf("%d",&n))    {        memset(c,0,sizeof(c)) ;        for(int i=1 ;i<=n ;i++)        {            scanf("%d",&T[i].x) ;            T[i].y=i ;        }        stable_sort(T+1,T+1+n,cmp) ;// 切记稳定排序        for(int i=1 ;i<=n ;i++)            b[T[i].y]=i ;        for(int i=1 ;i<=n ;i++)        {            int x=get_su(b[i])+1 ;// 自身也是一个 so +1             update(b[i],x) ;// 在比它大的值那更新        }        printf("%d\n",get_su(n)) ;    }    return 0 ;}


 

0 0
原创粉丝点击