HDU - 5225 Tom and permutation

题目大意:Tom学会了通过写程序求出一个1-n的排列的逆序对数,但他的老师给了他一个难题:

给出一个1-n的排列,求所有字典序比它小的1-n的排列的逆序对数之和。

Tom一时不知道该怎么做,所以他来找你帮他解决这个问题。

因为数可能很大,答案对109+7取模。

解题思路:从1到n枚举k,表示当前要计算的排列与读入的排列前k-1项相同,而第k项不同。对于每一个k,再枚举一个t,表示当前要计算的排列的第k项是t,所以t要比读入的排列的第k项小,并且不与前k-1个数中的任意一个数相等。

那么,剩下的n-k个数任意排列,都满足字典序小于读入的排列。所以要计算它们的逆序对数之和。可以分情况计算:

1、逆序对中的两个数都在前k-1个位置,可以对于每一个k都暴力计算。

2、逆序对中的一个数在前k-1个位置,另一个数不在,同样可以对于每一个k都暴力计算。

3、逆序对中的一个数在第k个位置,另一个数在后n-k个位置。也可以暴力计算。

4、逆序对中的两个数都在后n-k个位置。这个值可以DP预处理,也可以推出一个式子直接计算。

可以这样考虑:在后n-k个位置中,有一半的排列方式中,第i小的数在第j小的数(i>j)的前面。共有(n-k)!种排列方式,所以对于一对数,有\frac{(n-k)!}{2}种排列方式中是逆序对。共\frac{(n-k)·(n-k-1)}{2}对数,所以这类逆序对共\frac{(n-k)·(n-k-1)·(n-k)!}{4}对。

时间复杂度:O({n}^{3})

#include <cstdio>

int main() {
    long long MOD = 1e9 + 7, DP[200] = {0}, per[200] = {1, 1};
    for (int i = 2; i < 101; i++) {
        DP[i] = (per[i - 1] * i * (i - 1) / 2 % MOD + i * DP[i - 1] % MOD) % MOD;
        per[i] = per[i - 1] * i % MOD;
    }

    int N, A[200];
    while (scanf("%d", &N) != EOF) {
        for (int i = 0; i < N; i++)
            scanf("%d", &A[i]);

        int vis[200] = {0};
        long long ans = 0, cnt = 0;
        for (int i = 0; i < N; i++) {
            for (int j = 1; j < A[i]; j++)
                if (!vis[j]) {
                    ans = (((ans + cnt * per[N - i - 1]) % MOD + DP[N - i - 1]) % MOD);
                    cnt++;
                }
            vis[A[i]] = 1;
        }
        printf("%lld\n", ans);
    }
    return 0;
}
时间: 2025-01-08 00:30:53

HDU - 5225 Tom and permutation的相关文章

hdu 5225 Tom and permutation(回溯)

题目链接:hdu 5225 Tom and permutation #include <cstdio> #include <cstring> #include <algorithm> using namespace std; typedef long long ll; const int maxn = 100; const int mod = 1e9+7; int N, ans, V[maxn + 5], A[maxn + 5]; ll S[maxn + 5], L[m

hdu5225 Tom and permutation(BestCoder Round #40)

Tom and permutation Accepts: 120 Submissions: 422 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) 问题描述 Tom学会了通过写程序求出一个1-n的排列的逆序对数,但他的老师给了他一个难题: 给出一个1-n的排列,求所有字典序比它小的1-n的排列的逆序对数之和. Tom一时不知道该怎么做,所以他来找你帮他解决这个问题. 因为数可能很大,

hdu Uncle Tom&#39;s Inherited Land*(1*2矩阵覆盖,最大匹配)

http://acm.hdu.edu.cn/showproblem.php?pid=1507 大致题意:在一个n*m的格子上,黑色的地方不可用,问在白色格子上最多可放多少1*2的矩阵. 思路:建图,每个白色格子与它临近的上下左右的白色格子建边,求最大匹配,答案为最大匹配/2,因为是双向图.最后输出匹配边时,当找到一组匹配边记得将该边标记,以防重复计算. #include <stdio.h> #include <algorithm> #include <set> #inc

hdu 5226 Tom and matrix

题意: Tom放学回家的路上,看到天空中出现一个矩阵.Tom发现,如果矩阵的行.列从0开始标号,第i行第j列的数记为a[i][j],那么a[i][j]=C(i,j) 如果i < j,那么a[i][j]=0 Tom突发奇想,想求一个矩形范围((x1,y1),(x2,y2))内所有数的和.Tom急着回家,当然不会自己算,所以就把任务交给你了. 因为数可能很大,答案对一个质数p取模. 限制: 0 <= x1 <= x2 <=1e5 0 <= y1 <= y2 <=1e5

组合数(Lucas定理) + 快速幂 --- HDU 5226 Tom and matrix

Tom and matrix Problem's Link:   http://acm.hdu.edu.cn/showproblem.php?pid=5226 Mean: 题意很简单,略. analyse: 直接可以用Lucas定理+快速幂水过的,但是我却作死的用了另一种方法. 方法一:Lucas定理+快速幂水过 方法二:首先问题可以转化为求(0,0),(n,m)这个子矩阵的所有数之和.画个图容易得到一个做法,对于n<=m,答案就是2^0+2^1+...+2^m=2^(m+1)-1,对于n>m

hdu 5224 Tom and paper

题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=5224 Tom and paper Description There is a piece of paper in front of Tom, its length and width are integer. Tom knows the area of this paper, he wants to know the minimum perimeter of this paper. Input I

[hdu5225][BC#40]Tom and permutation

好久没写题解了..GDKOI被数位DP教做人了一发,现在终于来填数位DP的大坑了>_<. 发现自己以前写的关于数位DP的东西...因为没结合图形+语文水平拙计现在已经完全看不懂了嗯. 看来看去感觉还是这篇关于数位DP的介绍靠谱:http://wenku.baidu.com/view/d2414ffe04a1b0717fd5dda8.html 想题的时候结合图形食用效果更佳. 题意是说,对于一个给定的n的排列,要求出 (所有字典序<给定排列的排列)的逆序对个数和. 预处理出f[i]表示i的

HDU 5224 Tom and paper(BestCoder Round #40)

题目链接:Tom and paper 题面: Tom and paper Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Total Submission(s): 679    Accepted Submission(s): 432 Problem Description There is a piece of paper in front of Tom, its length

HDU5225 Tom and permutation(排列组合)

题意: Tom学会了通过写程序求出一个1-n的排列的逆序对数,但他的老师给了他一个难题: 给出一个1-n的排列,求所有字典序比它小的1-n的排列的逆序对数之和. Tom一时不知道该怎么做,所以他来找你帮他解决这个问题. 因为数可能很大,答案对109+7取模. 从前往后推,先计算1-k的所有排列可以产生逆序总数, 先假设db[2]为1-2的结果,那么我们来看3的排列,他是由1[2,3],2[1,3],3[1,2]三项组成,[]为所有排列的意思,第一项中[2,3]组合对结果贡献db[2],前面的1小