zoukankan      html  css  js  c++  java
  • dp

    对于一个数列{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; 100%的数据 n<=1000,k<=1000
     
    题意:让你求长度为 N 的序列逆序数为K的有多少种情况
    思路分析:考虑在增加一位,第 i 位时,就相当于在长度为i-1的序列全排列中插入以个 i ,由于插入的 i 值是最大的,因此其可以增加的逆序数数量为 0~i-1 ,当将 i 插入到最末尾时,不会增加任何逆序数,当插入到倒数第二位时,会增加一位逆序数,就这样推一下就可以了。
    定义 dp[i][j] 长度为 i 的序列逆序数为 j 的方案总数,在累加求和时要用前缀和优化一下
    代码示例:
    int dp[1005][1005];
    int sum[1005];
    
    int main() {
        //freopen("in.txt", "r", stdin);
        //freopen("out.txt", "w", stdout);
        int n, k;
        
        cin >> n >> k;
        
        dp[0][0] = 0;
        for(int i = 1; i <= n; i++){
            dp[i][0] = 1;
            for(int j = 1; j <= k; j++){
                int s = max(0, j-i+1);
                int e = j;
                if (s == 0) dp[i][j] = sum[e];
                else dp[i][j] = (sum[e]+mod-sum[s-1])%mod;
            } 
            sum[0] = 1;
            for(int j = 1; j <= k; j++) {
                sum[j] = sum[j-1]+dp[i][j];
                sum[j] %= mod;
            }
        }
        printf("%d
    ", dp[n][k]);
        return 0;
    }
    
    东北日出西边雨 道是无情却有情
  • 相关阅读:
    为什么比特币和以太坊未必真得比EOS更去中心化?
    为什么我说IPFS社区从卖矿机开始,就是错的
    人群捕捞,不知不觉控制你
    Maven解决repository不更换的问题
    Ubuntu安装mysql-proxy
    Ubuntu的NTP同步时钟设置方法
    MySQL索引原理及慢查询优化
    MySQL对比清除不必要的表
    MySQL5.7绿色版安装
    Ubuntu下监控服务
  • 原文地址:https://www.cnblogs.com/ccut-ry/p/9363868.html
Copyright © 2011-2022 走看看