本文主要是介绍HDU 2227 Find the nondecreasing subsequences,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
题目链接~~>
做题感悟:开始想到用 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 __int64
const 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 ;
}
这篇关于HDU 2227 Find the nondecreasing subsequences的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!