• 逆序对数列(BZOJ 2431)


    题目描述

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

    输入

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

    输出

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

    样例输入

    4 1
    样例输出

    3

    样例说明:

    下列3个数列逆序对数都为1;分别是1 2 4 3 ;1 3 2 4 ;2 1 3 4;

    测试数据范围

    30%的数据 n<=12

    100%的数据 n<=1000,k<=1000
    /*
      设f[i][j]为前i个数,逆序对数为j的方案数 
      在i-1个数中加入一个数,新增逆序对数为0~i-1,所以f[i][j]=Σf[i-1][k] (j-i+1<=k<=j)
      时间复杂度为O(n^3),采用前缀和优化:f[i][j]=g[i-1][j]-g[i-1][j-i] 
    */ 
    #include<cstdio>
    #include<iostream>
    #define M 1010
    #define Mod 10000
    using namespace std;
    int f[M][M],g[M][M];
    int read()
    {
        char c=getchar();int flag=1,num=0;
        while(c<'0'||c>'9'){if(c=='-')flag=-1;c=getchar();}
        while(c>='0'&&c<='9'){num=num*10+c-'0';c=getchar();}
        return num*flag;
    }
    int main()
    {
        int n=read(),k=read();
        f[0][0]=1;
        for(int i=0;i<=k;i++)g[0][i]=1;
        for(int i=1;i<=n;i++)
          for(int j=0;j<=k;j++)
          {
              f[i][j]=g[i-1][j];
              if(j-i>=0)f[i][j]=(f[i][j]+Mod-g[i-1][j-i])%Mod;
              if(j)g[i][j]=g[i][j-1];
              g[i][j]+=f[i][j];
              g[i][j]%=Mod;
          }
        printf("%d",f[n][k]);
        return 0;
    }
    View Code
  • 相关阅读:
    pip国内源
    高级信息系统项目管理师十大管理优秀范文
    DOM是什么
    js中!!的妙用
    Angular中@Output()的使用方法
    Js数组内对象去重
    JS去除对象或数组中的空值('',null,undefined,[],{})
    JS数组与字符串相互转换
    Js删除数组中的空值
    promise.all的应用场景举例
  • 原文地址:https://www.cnblogs.com/harden/p/5710386.html
Copyright © 2020-2023  润新知