传送门

目前只会n2" role="presentation" style="position: relative;">n2n2的dp" role="presentation" style="position: relative;">dpdp做法。

设dp[i][j]" role="presentation" style="position: relative;">dp[i][j]dp[i][j]表示1" role="presentation" style="position: relative;">11~i" role="presentation" style="position: relative;">ii的排列逆序对为j" role="presentation" style="position: relative;">jj的方案数。显然这个东西是可以递推的。相当于将i" role="presentation" style="position: relative;">ii插入到1" role="presentation" style="position: relative;">11~i−1" role="presentation" style="position: relative;">i−1i−1的排列中,然后就可以从dp[i−1][k]" role="presentation" style="position: relative;">dp[i−1][k]dp[i−1][k]转移过来。

然后我们就惊奇的发现这个方法是O(n3)" role="presentation" style="position: relative;">O(n3)O(n3)的,显然会T" role="presentation" style="position: relative;">TT掉。

如何优化?

仔细观察会发现,dp[i][j]" role="presentation" style="position: relative;">dp[i][j]dp[i][j]是由dp[i−1]" role="presentation" style="position: relative;">dp[i−1]dp[i−1]的前缀和转移过来的,因此每次枚举i" role="presentation" style="position: relative;">ii之后,我们维护一个叫做sum" role="presentation" style="position: relative;">sumsum的东西来表示dp[i−1]" role="presentation" style="position: relative;">dp[i−1]dp[i−1]的前缀和然后就能O(n2)" role="presentation" style="position: relative;">O(n2)O(n2)转移了。

代码如下:

#include<bits/stdc++.h>
#define N 1005
#define mod 10000
using namespace std;
inline int read(){
    int ans=0;
    char ch=getchar();
    while(!isdigit(ch))ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+ch-'0',ch=getchar();
    return ans;
}
int dp[N][N],ans=0,n,k;
int main(){
    n=read(),k=read();
    memset(dp,0,sizeof(dp));
    dp[1][0]=1;
    for(int i=2;i<=n;++i){
        ans=0;
        for(int j=0;j<=k;++j){
            ans=(ans+dp[i-1][j])%mod;
            dp[i][j]=ans%mod;
            if(j+1-i>=0)ans=(ans-dp[i-1][j-i+1]+mod)%mod;
        }
    }

    printf("%d",dp[n][k]);
    return 0;
}

2018.07.18 HAOI2009 逆序对数列(线性dp)的更多相关文章

  1. BZOJ2431 HAOI2009 逆序对数列 【DP】*

    BZOJ2431 HAOI2009 逆序对数列 Description 对于一个数列ai{a_i}ai​,如果有i<j且ai>aja_i>a_jai​>aj​,那么我们称aia ...

  2. BZOJ 2431: [HAOI2009]逆序对数列【dp】

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

  3. 【BZOJ 2431】 [HAOI2009] 逆序对数列 (DP)

    Description 对于一个数列{ai},如果有iaj,那么我们称ai与aj为一对逆序对数.若对于任意一个由1~n自然数组成的 数列,可以很容易求出有多少个逆序对数.那么逆序对数为k的这样自然数数 ...

  4. [luogu2513 HAOI2009] 逆序对数列 (计数dp)

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

  5. bzoj2431: [HAOI2009]逆序对数列(DP)

    f[i][j]前i个数有j个逆序对的数量 f[i][j]=sigma(f[i-1][j-k]){1<=k<=i} 维护一个前缀和即可 #include<iostream> #i ...

  6. 【洛谷 P2513】 [HAOI2009]逆序对数列(DP)

    题目链接 这种求方案数的题一般都是\(dp\)吧. 注意到范围里\(k\)和\(n\)的范围一样大,\(k\)是完全可以更大的,到\(n\)的平方级别,所以这暗示了我们要把\(k\)写到状态里. \( ...

  7. BZOJ 2431 [HAOI2009]逆序对数列:dp 逆序对

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=2431 题意: 给定n,k,问你有多少个由1~n组成的排列,使得逆序对个数恰好为k个. 题解 ...

  8. [luoguP2513] [HAOI2009]逆序对数列(DP)

    传送门 f[i][j]表示前i个数,逆序对数为j的答案 则DP方程为: f[1][0] = 1; for(i = 2; i <= n; i++) for(j = 0; j <= m; j+ ...

  9. bzoj2431:[HAOI2009]逆序对数列

    单组数据比51nod的那道题还弱...而且连优化都不用了.. #include<cstdio> #include<cstring> #include<cctype> ...

随机推荐

  1. Eclipse 中yml自动提示功能相关设置

    转自:https://blog.csdn.net/lililuni/article/details/82849376

  2. require.js 学习基础

    RequireJS 是一个JavaScript模块加载器,他的目标是鼓励代码的模块化,它使用了不同于传统<script>标签的脚本加载步骤.可以用它来加速.优化代码,但其主要目的还是为了代 ...

  3. JS实现拖动效果

    有个问题就是该模块要使用定位,因为有left,top属性使用,绝对定位和相对定位都行,当然你也可使用margin-left,和margin-top这2个属性,替换left,top也是可以得 这样就不用 ...

  4. delphi const的用法

    unit RadKeygen; interface uses Classes,SysUtils,Windows; function fun1():string; implementation cons ...

  5. mongodb基础学习11-复制集和分片结合使用

    实际的使用中复制集和分片是结合使用的,即一个分片由一个复制集构成,多个分片存储数据库的数据 调用脚本启动两个复制集 启动configsvr的节点 启动mongos 增加分片,这次要加上复制集的id,节 ...

  6. springMVC学习记录2-使用注解配置

    前面说了一下使用xml配置springmvc,下面再说说注解配置.项目如下: 业务很简单,主页和输入用户名和密码进行登陆的页面. 看一下springmvc的配置文件: <?xml version ...

  7. 漫画描述HDFS工作原理

    作者不详,内容浅显易懂,特拿来与大家分享.

  8. Boost.Coroutine2:学习使用Coroutine(协程)

    function(函数)routine(例程)coroutine (协程) 函数,例程以及协程都是指一系列的操作的集合. 函数(有返回值)以及例程(没有返回值)也被称作subroutine(子例程), ...

  9. Delphi 动态数组合并

    TIntArray = array of Integer; function MergeArray(const ArrayA, ArrayB: TIntArray): TIntArray; var i ...

  10. scala sparseVetor, SprseMatrix 实现

    def rand(seed:Int):Double={ val rand=new Random(seed) rand.nextDouble()} def rand2(size:Int,seed:Int ...