zoukankan      html  css  js  c++  java
  • BZOJ4361 isn 【树状数组优化DP】*

    BZOJ4361 isn


    Description

    给出一个长度为n的序列A(A1,A2…AN)。如果序列A不是非降的,你必须从中删去一个数,这一操作,直到A非降为止。求有多少种不同的操作方案,答案模10^9+7。

    Input

    第一行一个整数n。
    接下来一行n个整数,描述A。

    Output

    一行一个整数,描述答案。

    Sample Input

    4
    1 7 5 3

    Sample Output

    18

    HINT

    1<=N<=2000


    我们可以设dp[i][j]是前i个数,选出包含i的j个数的方案数,然后我们发现转移其实很显然,dp[i][j]=dp[k][j1],然后这玩意可以树状数组维护一下就优化下来了

    然后贼优秀

    #include<bits/stdc++.h>
    using namespace std;
    #define LL long long
    #define inf 0x3f3f3f3f
    #define N 2010
    #define yyf 1000000007
    LL n,newn,a[N],b[N],J[N];
    LL t[N][N],dp[N];
    void add(LL &a,LL b){a=(a+b)%yyf;}
    void add(LL k,LL pos,LL vl){for(;pos<=newn;pos+=pos&(-pos))add(t[k][pos],vl);}
    LL query(LL k,LL pos){LL res=0;for(;pos;pos-=pos&(-pos))add(res,t[k][pos]);return res;}
    int main(){
        scanf("%lld",&n);
        J[0]=1;for(LL i=1;i<=n;i++)J[i]=1ll*i*J[i-1]%yyf;
        for(LL i=1;i<=n;i++)scanf("%lld",&a[i]),b[i]=a[i];
        sort(b+1,b+n+1);
        newn=unique(b+1,b+n+1)-b-1;
        for(LL i=1;i<=n;i++)a[i]=lower_bound(b+1,b+newn+1,a[i])-b;
        add(0,1,1);
        for(LL i=1;i<=n;i++)
            for(LL j=i;j>=1;j--){
                LL tmp=query(j-1,a[i]);
                add(dp[j],tmp);
                add(j,a[i],tmp);
            }
        LL ans=0;
        for(LL i=1;i<=n;i++){
            add(ans,J[n-i]*dp[i]%yyf);
            if(i!=n)add(ans,yyf-J[n-i-1]*(i+1)%yyf*dp[i+1]%yyf);
        }
        printf("%lld
    ", ans);
        return 0;
    }
    
  • 相关阅读:
    Python 读写
    测试项目总结之手淘安全中心
    Python 单元测试
    Python __name__变量
    java数据类型取值范围
    java数据类型之间的转换
    Git 常用命令清单
    Linux Distribution
    UNIX&Linux发展图谱
    Linux 软件大全
  • 原文地址:https://www.cnblogs.com/dream-maker-yk/p/9676319.html
Copyright © 2011-2022 走看看