zoukankan      html  css  js  c++  java
  • 洛谷 P2513 [HAOI2009]逆序对数列

    题目描述

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

    输入输出格式

    输入格式:

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

    输出格式:

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

    输入输出样例

    输入样例#1:
    4 1
    输出样例#1:
    3

    说明

    样例说明:

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

    测试数据范围

    30%的数据 n<=12

    100%的数据 n<=1000,k<=1000

    一道简单题,但我觉得可以做到更大的数据,比方说加两个0

    从小到大考虑每一位,先考虑1,如果1位于i这个位置,那1与1~i-1这些位置的每一个数都会产生一个逆序对,与i+1~n这些位置的数都不会产生逆序对,至于具体每个数字是什么对于1的贡献没有影响

    然后从排列里把1去掉,变成一个2~n的排列,这个排列与1~n-1的排列是等价的,于是问题转化成了一个较小的问题

    然后可以dp

    dp[i][j]表示1~i的排列,要有j个逆序对的方法数,枚举当前位置产生的逆序对来转移,这个东西本来是nk^2的,但是发现一个位置转移的时候是连续的一段,用前缀和优化去掉一个k即可

    其实这个问题等价于有n个带编号的盒子排成一列,一共放k个球,标号为i的盒子里不能放超过i-1个球,求方法总数,这应该是有更好的做法的

    UPD1:这个东西的生成函数是 $ (1)(1+x)(1+x+x^2)(1+x+x^2+x^3)...(1+x+x^2+...+x^{n-1}) $ 即 $ prod_{p=1}^{n}sum_{q=0}^{p-1}x^q $ ,这个形式过于美妙让人很难不认为它有一个优美的通解

     1 #include <iostream>
     2 #include <cstdlib>
     3 #include <cstdio>
     4 #include <algorithm>
     5 #include <string>
     6 #include <cstring>
     7 #include <cmath>
     8 #include <map>
     9 #include <stack>
    10 #include <set>
    11 #include <vector>
    12 #include <queue>
    13 #include <time.h>
    14 #define eps 1e-7
    15 #define INF 0x3f3f3f3f
    16 #define MOD 10000
    17 #define rep0(j,n) for(int j=0;j<n;++j)
    18 #define rep1(j,n) for(int j=1;j<=n;++j)
    19 #define pb push_back
    20 #define mp make_pair
    21 #define set0(n) memset(n,0,sizeof(n))
    22 #define ll long long
    23 #define ull unsigned long long
    24 #define iter(i,v) for(edge *i=head[v];i;i=i->nxt)
    25 #define max(a,b) (a>b?a:b)
    26 #define min(a,b) (a<b?a:b)
    27 #define print_runtime printf("Running time:%.3lfs
    ",double(clock())/1000.0)
    28 #define TO(j) printf(#j": %d
    ",j);
    29 //#define OJ
    30 using namespace std;
    31 const int MAXINT = 100010;
    32 const int MAXNODE = 100010;
    33 const int MAXEDGE = 2*MAXNODE;
    34 char BUF,*buf;
    35 int read(){
    36     char c=getchar();int f=1,x=0;
    37     while(!isdigit(c)){if(c=='-') f=-1;c=getchar();}
    38     while(isdigit(c)){x=x*10+c-'0';c=getchar();}
    39     return f*x;
    40 }
    41 char get_ch(){
    42     char c=getchar();
    43     while(!isalpha(c)) c=getchar();
    44     return c;
    45 }
    46 //------------------- Head Files ----------------------//
    47 
    48 int n,k;
    49 int dp[10010],sum[10010];
    50 void get_input();
    51 void work();
    52 int main() {
    53     get_input();
    54     work();
    55     return 0;
    56 }
    57 void work(){
    58     fill(sum,sum+k+1,1);
    59     for(int i=2;i<=n;i++){ //box no i,can take 0~i-1
    60         rep0(j,k+1){
    61             dp[j] = (j-i+1>0?sum[j]-sum[j-i]:sum[j]);
    62         }
    63         sum[0]=dp[0];
    64         rep1(j,k){
    65             sum[j]=(sum[j-1]+dp[j])%MOD;
    66         }
    67     }
    68     printf("%d
    ",(dp[k]+MOD)%MOD);
    69 }
    70 void get_input(){
    71        n=read();k=read();
    72 }
  • 相关阅读:
    使用npm安装包失败的解决办法(使用npm国内镜像介绍)
    JavaScript的变量、作用域和内存问题
    JavaScript的基本概念
    在Html中使用JavaScript
    JavaScript简介
    C++为了兼容,所以并不是纯面向对象编程语言
    C++四种不同的对象生存方式
    Java BigDecimal使用
    ext 对齐
    ext grid 子表格
  • 原文地址:https://www.cnblogs.com/LoveYayoi/p/6921138.html
Copyright © 2011-2022 走看看