zoukankan      html  css  js  c++  java
  • [Swust OJ 541]--排列字典序问题

    题目链接:http://acm.swust.edu.cn/problem/0541/

    Time limit(ms): 2000      Memory limit(kb): 65535

    n个元素{1,2,..., n }有n!个不同的排列。将这n!个排列按字典序排列,并编号为0,1,…,n!-1。每个排列的编号为其字典序值。例如,当n=3时,6 个不同排列的字典序值如下: 


    0       1     2    3     4    5


    123 132 213 231 312 321


    任务:给定n 以及n 个元素{1,2,..., n }的一个排列,计算出这个排列的字典序值,以及按字典序排列的下一个排列。

    Description

    第1 行是元素个数n(n < 15)。接下来的1 行是n个元素{1,2,..., n }的一个排列。

    Input

    第一行是字典序值,第2行是按字典序排列的下一个排列。

    Output
    1
    2
    8
    2 6 4 5 8 1 7 3
    Sample Input
    1
    2
    8227
    2 6 4 5 8 3 1 7
    Sample Output
     
     
    解题思路:两部曲(咳咳~~)
    一题目例子为例

    比2小的数有1个,则 tot+=1*7!;

    比6小的数有4个,则 tot+=4*6!;

    比4小的数有2个,则 tot+=2*5!;

    比5小的数有2个,则 tot+=2*4!;

    比8小的数有3个,则 tot+=3*3!;

    比1小的数有0个,则 tot+=0*2!;

    比7小的数有1个,则 tot+=1*1!;

    比3小的数没有;

    在实际求解中可以通过减去前面比当前数小的数来确定后面当前数小的数(方便程序的编写)
     
    对于求下一个序列,冲最后找,找到一个比最后一个数小的数把最后一个数放在之前就可以了
    当然懒人嘛(比如说我)就next_permutation()你值得拥有~~~
     
    代码如下
     1 #include <iostream>
     2 #include <algorithm>
     3 using namespace std;
     4 int main()
     5 {
     6     int n, i, j, k, t, *p, x[16];
     7     x[0] = 1;
     8     for (i = 1; i < 15; i++)
     9         x[i] = x[i - 1] * i;
    10     while (cin >> n)
    11     {
    12         k = 0;
    13         p = new int[n + 1];
    14         for (i = 0; i < n; i++)
    15             cin >> p[i];
    16         for (i = 0; i < n - 1; i++)
    17         {
    18             t = p[i] - 1;
    19             for (j = 0; j < i; j++)
    20             if (p[j] < p[i])
    21                 t--;
    22             k += t*x[n - i - 1];
    23         }
    24         cout << k << endl;
    25         next_permutation(p, p + n);
    26         for (i = 0; i < n; i++)
    27             cout << p[i] << ' ';
    28         cout << endl;
    29     }
    30     return 0;
    31 }
    View Code
     用数位dp还是超时了(其实就这个状态设计本身来说不超时才是怪事,不想多说),代码先放在这里
     1 /*******************数位dp*************************/
     2 #include <iostream>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 int n, bit[11], vis[10], flag;
     7 char s[11];
     8 
     9 int dfs(int pos, bool limit){
    10     if (pos >= n) return 1;
    11     int last = limit ? bit[pos] : n;
    12     int ret = 0;
    13     for (int i = 1; i <= last; i++){
    14         if (vis[i]) continue;
    15         vis[i] = 1;
    16         ret += dfs(pos + 1, limit&&i == last);
    17         vis[i] = 0;
    18     }
    19     return ret;
    20 }
    21 
    22 int main(){
    23     cin >> n;
    24     for (int i = 0; i < n; i++) cin >> bit[i];
    25     cout << dfs(0, 1) - 1 << endl;
    26     next_permutation(bit, bit + n);
    27     for (int i = 0; i < n; i++)
    28         cout << bit[i] << ' ';
    29     cout << endl;
    30     return 0;
    31 }
    View Code
  • 相关阅读:
    vue 中input的输入限制
    PC端百度地理围栏、绘制工具以及判断当前坐标是否再围栏中
    js判断鼠标点击的是哪个键
    vue过滤器的使用
    3.Mybatis的配置解析
    2.MyBatis的CRUD操作
    4.JVM类加载器深入解析及重要特性剖析
    3.JVM的接口初始化规则与类加载器准备阶段和初始化阶段的重要意义分析
    2.JVM的类加载器
    1.JVM如何学习
  • 原文地址:https://www.cnblogs.com/zyxStar/p/4563936.html
Copyright © 2011-2022 走看看