• Educational Codeforces Round 80 C. Two Arrays


    http://codeforces.com/contest/1288/problem/C

    题意:

    用1—n构造两个长为m的数组a,b

    满足a[i]<=b[i],a单调不减,b单调不增

    求方案数

    令dp[i][j][k] 表示构造了长度为i,a[i]=j,b[i]=k的方案数

    dp[i][j][k]=Σ dp[i-1][h][p] (h<=p,h<=i,p>=k)

    时间复杂度:m*n^4

    前缀和、后缀和 优化:

    sum[i][j][k] 表示 Σ dp[i][1—j][k—n]

    求的时候可以先用后缀和算 sum[i][j][k]=Σ dp[i][j][k—n]

    再用前缀和算 sum[i][j][k]=Σ sum[i][1—j][k]

    #include<cstdio>
     
    using namespace std;
     
    const int mod=1e9+7;
     
    int dp[11][1001][1001],sum[11][1001][1001];
     
    int main()
    {
        int n,m;
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
        {
            for(int j=i;j<=n;++j) 
            {
                dp[1][i][j]=1;
                sum[1][i][j]=1;
            }
            for(int j=n-1;j>=i;--j) sum[1][i][j]+=sum[1][i][j+1];
        }
        for(int j=1;j<=n;++j)
            for(int k=2;k<=j;++k)
                sum[1][k][j]+=sum[1][k-1][j];
        for(int i=2;i<=m;++i)
        {
            for(int j=1;j<=n;++j)
            {
                for(int k=j;k<=n;++k)
                {
                    dp[i][j][k]=sum[i-1][j][k];
                    sum[i][j][k]=dp[i][j][k];
                }
                for(int k=n-1;k>=j;--k) sum[i][j][k]=(sum[i][j][k]+sum[i][j][k+1])%mod;
            }
            for(int k=1;k<=n;++k)
                for(int j=2;j<=k;++j)
                    sum[i][j][k]=(sum[i][j][k]+sum[i][j-1][k])%mod;
        }
        int ans=0;
        for(int i=1;i<=n;++i)
            for(int j=i;j<=n;++j)
                ans=(ans+dp[m][i][j])%mod;
        printf("%d",ans);
    }
  • 相关阅读:
    计数排序
    CSS3变形
    前端内存泄露问题
    复杂对象的深拷贝
    JavaScript基本数据类型——Symbol
    随机打乱数组
    唯一重复的数字
    src和href的区别
    iframe的缺点
    link和@import的区别
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/12219373.html
Copyright © 2020-2023  润新知