zoukankan      html  css  js  c++  java
  • [BZOJ 2431] [HAOI2009] 逆序对数列

    2431: [HAOI2009]逆序对数列

    Time Limit: 5 Sec
    Memory Limit: 128 MB

    Description

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

    Input

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

    Output

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

    Sample Input

    样例输入

    4 1

    Sample Output

    样例输出

    3

    样例说明:

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

    测试数据范围

    30%的数据 n<=12

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

    HINT

    【题解】

    首先,我们可以想到,f[i][j]表示i个数有j个逆序对的数列个数,那么f[i][j]=sigma f[i-1][j-k] (0<=k<i)

    然后发现这是O(n^3)的,我就不会优化了TAT

    后来看了jry大神的博客 发现可以用前缀和进行优化

    然后就A了,我果然还是tyts (too young too simple)

    不小心写f[i]=f[i]%10000 WA了一次QAQ

     1 #include <cstdio>
     2 using namespace std;
     3 int f[1001][1001],t,n,k;
     4 //f[i][j]表示i个数,有j个逆序对的数列的个数 
     5 int main() {
     6     scanf("%d%d",&n,&k);
     7     for (int i=1;i<=n;++i) f[i][0]=1;
     8     for (int i=2;i<=n;++i) {
     9         t=f[i-1][0];
    10         for (int j=1;j<=k;++j) {
    11             if(j-i>=0) t-=f[i-1][j-i];
    12             t+=f[i-1][j];
    13             f[i][j]=(t+10000)%10000;
    14         } 
    15     }
    16     printf("%d
    ",f[n][k]);
    17     return 0;
    18 }
    View Code
  • 相关阅读:
    希腊字母写法
    The ASP.NET MVC request processing line
    lambda aggregation
    UVA 10763 Foreign Exchange
    UVA 10624 Super Number
    UVA 10041 Vito's Family
    UVA 10340 All in All
    UVA 10026 Shoemaker's Problem
    HDU 3683 Gomoku
    UVA 11210 Chinese Mahjong
  • 原文地址:https://www.cnblogs.com/TonyNeal/p/bzoj2431.html
Copyright © 2011-2022 走看看