• hdu4991 树状数组+dp


    这题说的是给了一个序列长度为n 然后求这个序列的严格递增序列长度是m的方案有多少种,如果用dp做那么对于状态有dp[n][m]=dp[10000][100],时间复杂度为n*m*n接受不了那么想想是否可以再这个上加些什么样的优化。树状数组 对于每个值离散在树状数组中然后对于每个点都有以他为结尾点的递增序列的长度为1..100,那么他的状态是怎么来的呢?当他的i长度的是等于在他前面比他来的小的 长度为i-1的的种数,然后得到了这个值将他在加进这第i棵树状数组中然后就得到解了,不断地进行这个过程时间n*m*log2(n);

    #include <iostream>
    #include <cstdio>
    #include <string.h>
    #include <algorithm>
    using namespace std;
    typedef int ll;
    const int MAX_N = 10005;
    const ll MOD = 123456789;
    ll C[105][MAX_N];
    ll A[MAX_N],B[MAX_N];
    int len;
    int lowbit(int x){
      return x&(-x);
    }
    void add(int x,ll value, int floor){
         while(x<=len){
            C[floor][x]=(C[floor][x]+value)%MOD;
            x+=lowbit(x);
         }
    }
    ll sum(int x, int floor){
        ll ans=0;
        while(x>0){
             ans=(ans+C[floor][x])%MOD;
             x-=lowbit(x);
        }
        return ans;
     }
    int main()
    {
         int n,m;
        while(scanf("%d%d",&n,&m)==2){
    
             for(int i=0; i<n; ++i){
                 scanf("%d",&A[i]);
                 B[i] = A[i];
             }
             sort( B , B + n );
             len = unique(B,B+n)-B;
             memset(C,0,sizeof(C));
             for(int i =0; i<n; ++i){
                 int loc = lower_bound(B,B+len,A[i])-B+1;
                 add(loc,1,1);
                 for(int j = 2; j<=m ; ++j ){
                    ll num = sum(loc-1,j-1);
                    add(loc,num,j);
                 }
             }
             ll ans = sum(len,m);
             printf("%d
    ",ans);
         }
         return 0;
    }
    View Code
  • 相关阅读:
    【2017-3-1】数组
    【2017-2-27】三大类
    【2017-2-25】 循环语句 跳转语句 迭代法 穷举法 异常语句
    【2017-02-22】if语句 if语句的嵌套 及巩固练习------------练习补充
    【2017-02-22】if语句 if语句的嵌套 及巩固练习
    【2017-02-20】C#基础 -- 阶段总结
    【2017-02-20】C#基础
    【2017-02-19】C#基础
    【2017-02-18】C#基础
    Windows 64位下安装Redis详细教程
  • 原文地址:https://www.cnblogs.com/Opaser/p/3962989.html
Copyright © 2020-2023  润新知