zoukankan      html  css  js  c++  java
  • HDU 5225 枚举

    题目链接:

    hdu:http://acm.hdu.edu.cn/showproblem.php?pid=5225

    bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=580&pid=1002

    题解:

    数组a保存输入

    考虑当前位i,对于1<=j<i,使得x[j]=a[j],对于第i位,枚举1<=x[i]<a[i],并且x[i]!=x[j](1<=j<i),这样,对于i<j<=n的部分,任意排列都是满足条件的

    这样,我们每次计算逆序对可以分为三个部分:

    1~i-1的贡献:

      计算出所有的a[j](即x[j])>a[k]的个数(1<=j<=i-1,j<k<=n)cnt1(可预处理出来)

    第i位的贡献:

      计算出所有的x[i]>a[k] (i<k<=n) cnt2

    由上面两部分得:1~i的贡献:cnt12 =(cnt1+cnt2)*(n-i)!

    最后考虑i+1~n的逆序对:

      在后n-i个位置中,有一半的排列方式中,第j小的数在第k小的数(j>k)的前面。共有(n-i)!种排列方式,所以对于一对数,有(n-i)!/2种排列方式中是逆序对。共有(n-i)*(n-i-1)/2对数,所有这类逆序对共(n-i)*(n-i-1)*(n-i)!/4对。

      即cnt3=(n-i)*(n-i-1)*(n-i)!/4

    综上:第i位的答案是cnt12+cnt3;

    注意:

      cnt3=(n-i)*(n-i-1)*(n-i)!/4,这里的4要在取模之前处理掉!!!取模之前处理掉!!!取模之前处理掉!!!

      总共4天提交了11次,CE了2次,wa了6次,ac了3次,最后一次ac告诉我,三天前错的地方就只有一个!除4没有提前处理!!!

    代码:

     1 #include<iostream>
     2 #include<cstring>
     3 #include<cstdio>
     4 using namespace std;
     5 
     6 const int maxn = 100 + 10;
     7 const int mod = 1e9 + 7;
     8 typedef long long LL;
     9 
    10 int arr[maxn], used[maxn];
    11 
    12 int n;
    13 
    14 LL cnt[maxn];
    15 void pre_for_solve() {
    16     memset(cnt, 0, sizeof(cnt));
    17     for (int i = 1; i <= n; i++) {
    18         cnt[i] = cnt[i - 1];
    19         for (int j = i + 1; j <= n; j++) {
    20             if (arr[i]>arr[j]) cnt[i]++;
    21         }
    22     }
    23 }
    24 
    25 LL fac[maxn], fac2[maxn];
    26 void get_fac() {
    27     memset(fac, 0, sizeof(fac));
    28     memset(fac2, 0, sizeof(fac2));
    29     //求1*3*4*...*n
    30     fac[0] = 1, fac[1] = 1, fac[2] = 1;
    31     for (int i = 3; i < maxn; i++) {
    32         fac[i] = fac[i - 1] * i%mod;
    33     }
    34     //求1*2*3...*n
    35     fac2[0] = 1;
    36     for (int i = 1; i<maxn; i++) {
    37         fac2[i] = fac2[i - 1] * i%mod;
    38     }
    39 }
    40 
    41 void init() {
    42     memset(used, 0, sizeof(used));
    43 }
    44 
    45 int main() {
    46     get_fac();
    47     while (scanf("%d", &n) == 1 && n) {
    48         init();
    49         for (int i = 1; i <= n; i++) scanf("%d", arr + i);
    50         pre_for_solve();
    51         LL ans = 0;
    52         for (int i = 1; i <= n; i++) {
    53             for (int x = 1; x<arr[i]; x++) {
    54                 if (!used[x]) {
    55                     //cnt1
    56                     LL sum = cnt[i - 1];
    57                     //cnt2
    58                     for (int xx = 1; xx <= n; xx++) {
    59                         if (!used[xx] && x>xx) sum++;
    60                     }
    61                     //cnt12
    62                     sum = sum*fac2[n - i] % mod;
    63                     //cnt3
    64                     LL tmp = fac[n - i] * (n - i)*(n - i - 1) / 2 % mod;
    65                     //cnt12+cnt3
    66                     sum = (sum + tmp) % mod;
    67                     ans += sum;
    68                     ans %= mod;
    69                 }
    70             }
    71             used[arr[i]] = 1;
    72         }
    73         printf("%lld
    ", ans);
    74     }
    75     return 0;
    76 }
  • 相关阅读:
    CentOS 7搭建vsftp服务
    Istio
    Kubernetes
    Kubernetes
    Kubernetes
    Kubernetes
    Kubernetes
    Kubernetes
    Kubernetes
    11.树的抽象数据类型和几种表示法
  • 原文地址:https://www.cnblogs.com/fenice/p/5406330.html
Copyright © 2011-2022 走看看