zoukankan      html  css  js  c++  java
  • dp+树状数组

    给定一个长度为 N 的序列 A,求 A有多少个长度为 M 的严格递增子序列。

    输入格式

    第一行包含整数 TT,表示共有 T 组测试数据。

    每组数据,第一行包含两个整数 N 和 M。

    第二行包含 N 个整数,表示完整的序列 A。

    输出格式

    每组数据输出一个结果,每个结果占一行。

    输出格式为 Case #x: yx 为数据组别序号,从 11 开始,yy 为结果。

    由于答案可能很大,请你输出对 1e9+7取模后的结果。

    数据范围

    1T100
    1MN1000
    Ti=1Ni×Mi1e7
    序列中的整数的绝对值不超过1e9

    输入样例:

    2
    3 2
    1 2 3
    3 2
    3 2 1
    

    输出样例:

    Case #1: 3
    Case #2: 0



    f[maxn][maxn];//以第i个结尾时,有j个递增的方案数
    优化之前的代码时这样的:
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn=1e3+100;
    const int mod=1e9+7;
    int a[maxn],t;
    int f[maxn][maxn];//以第i个结尾时,有j个递增的方案书 
    int n,m;
    int main(){
        cin>>t;
        int kase=0;
        while(t--){
            memset(f,0,sizeof(f));
            cin>>n>>m;
            for(int i=1;i<=n;i++){
                cin>>a[i];
            }
            f[1][1]=1;
            for(int i=1;i<=n;i++){
                f[i][1]=1;
            }
            for(int i=2;i<=n;i++){
                for(int j=1;j<m;j++){
                    for(int k=1;k<i;k++){ 
                        if(a[i]>a[k]){
                            f[i][j+1]+=f[k][j];    
                        }
                        f[i][j+1]%=mod;
                    } 
                }
            }
            int ans=0;
            for(int i=1;i<=n;i++){
                //cout<<f[i][m]<<endl;
                ans+=f[i][m];
                ans%=mod; 
            }
            printf("Case #%d: %d
    ",++kase,ans);
        } 
        
    }
    然后可以用线段树或者树状数组优化掉一维
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    typedef long long ll;
    using namespace std;
    const int maxn=1e3+100;
    const int mod=1e9+7;
    int a[maxn],t;
    int f[maxn][maxn];//以第i个结尾时,有j个递增的方案数 
    int n,m;
    int cnt=0; 
    int c[maxn]; 
    int num[maxn];
    int lowbit(int x){
        return x&-x;
    }
    void add(int x,int k){
        for(int i=x;i<=cnt;i+=lowbit(i)){
            c[i]=(c[i]+k)%mod;
        }
    }
    int getsum(int x){
        int ans=0;
        for(int i=x;i>0;i-=lowbit(i)){
            ans=(ans+c[i])%mod; 
        }
        return ans;
    }
    int main(){
        cin>>t;
        int kase=0;
        while(t--){
            memset(f,0,sizeof(f));
            cin>>n>>m;
            cnt=0;
            for(int i=1;i<=n;i++){
                cin>>a[i];
                num[++cnt]=a[i];
            }
            sort(num+1,num+cnt+1);
            cnt=unique(num+1,num+cnt+1)-(num+1); 
            for(int i=1;i<=n;i++){
                a[i]=lower_bound(num+1,num+cnt+1,a[i])-num;
            }
            for(int i=1;i<=n;i++){
                f[i][1]=1;
            }
            for(int j=2;j<=m;j++){
                for(int i=1;i<=cnt;i++){
                    c[i]=0;
                } 
                for(int i=1;i<=n;i++){
                    f[i][j]=getsum(a[i]-1);
                    add(a[i],f[i][j-1]);
                }
            }
            int ans=0;
            for(int i=1;i<=n;i++){
                ans+=f[i][m];
                ans%=mod; 
            }
            printf("Case #%d: %d
    ", ++kase,ans);
        }
    } 
     


  • 相关阅读:
    屏幕录像专家V7.5(完美破解版,无水印)下载
    常用前端插件推荐
    C#编写QQ找茬外挂
    wp-content-index文章目录插件使用效果调整
    C#读取Word文档内容代码
    js获取当前url地址及参数
    http状态码对应表
    应用程序利用回调向表现层实时推送数据
    解除网页右键限制和开启网页编辑状态的js代码
    IDEA中隐藏.iml文件
  • 原文地址:https://www.cnblogs.com/lipu123/p/14533710.html
Copyright © 2011-2022 走看看