zoukankan      html  css  js  c++  java
  • 逆序对数列

    【题目描述】

    对于一个数列{a[]},如果有i<j且a[i]>a[j],那么我们称a[i]与a[j]为一对逆序对数。若对于任意一个由1~n自然数组成的数列,可以很容易求出有多少个逆序对数。询问逆序对数为k的这样自然数数列到底有多少个。

    【输入描述】

     第一行为两个整数n、k。

    【输出描述】

    写入一个整数,表示符合条件的数列个数,由于这个数可能很大,你只需输出该数对10000求余数后的结果。

    【输入样例】

    4 1

    【输出样例】

    3

    【数据范围】

    下列3个数列逆序对数都为1,分别是:

    1 2 4 3

    1 3 2 4

    2 1 3 4
    n <= 1000,k <= 1000。

    BZOJ的数据太水了,O(m*n^2)的普通解法竟然过了:

    源代码:
    
    #include<cstdio>
    int m,n,f[1001][1001]={0};
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int a=1;a<=n;a++) //初始化边界。
          f[a][0]=1;
        for (int a=1;a<=n;a++)
          for (int b=1;b<=m;b++)
            for (int c=1;c<=a;c++)
              if (b-a+c>=0) //避免越界溢出。
                f[a][b]=(f[a][b]+f[a-1][b-a+c])%10000;
        printf("%d",f[n][m]);
        return 0;
    }
    
    /*
        挺简单的DP:
            f[i][j]表示1~i个自然数所组合成的、逆序对数为j的数列个数。
            在1~i中,i即为最大,故将它安插到某一位置,其后方的所有数都会与它形成逆序对。
            由上可得状态转移方程:
                f[i][j] = ∑f[i-1][j-i+k],(1 <= k <= i)。
    */

    滚动数组+前缀和优化后的O(mn)解法:

    源代码:
    
    #include<cstdio>  
    int m,n,sum[1001],f[1001];
    int main()
    {
        scanf("%d%d",&n,&m);
        for (int a=0;a<=m;a++) //除f[1][0]为1外,f[1][j]皆为0。
          sum[a]=1;
        for (int a=2;a<=n;a++) //直接从f[2][]开始。
        {
            f[0]=1; //f[i][0]显然为1。
            for (int b=1;b<=m;b++)
              if (b-a>=0)
              {
                f[b]=sum[b]-sum[b-a];
                while (f[b]<0) //注意此处理,避免因负数而出现错误。
                  f[b]+=10000;
              }
              else
                f[b]=sum[b];
            for (int b=1;b<=m;b++) //前缀和处理。
              sum[b]=(sum[b-1]+f[b])%10000;
        }
        printf("%d",f[m]);
        return 0;
    }
  • 相关阅读:
    今日SGU 5.2
    奇异值分解(SVD)小结
    计蒜客16495 Truefriend(fwt)
    计蒜客16492 building(二分线段树/分块)
    hihocoder 1323 回文字符串(字符串+dp)
    hihocoder 1320 压缩字符串(字符串+dp)
    hdu6121 build a tree(树)
    hdu6103 Kirinriki(trick+字符串)
    hdu6097 Mindis(几何)
    hdu 6057 Kanade's convolution(子集卷积)
  • 原文地址:https://www.cnblogs.com/Ackermann/p/5709871.html
Copyright © 2011-2022 走看看