洛谷 P2524 Uim的情人节礼物·其之弐(康拓展开)

题目: P2524 Uim的情人节礼物·其之弐: https://www.luogu.org/problemnew/show/P2524


题目描述

前传:详见洛谷P2525

Uim成功地按照顺序将礼物送到了N个妹子的手里并维持她们的和谐。

Uim现在想知道,他最终选择的顺序是所有给N个妹子送礼顺序中、字典序第几小的。

输入输出格式

输入格式:

第一行一个整数N,表示有N个数。

第二行一个整数X,表示给出的排列。

输出格式:

一个整数,表示是第几小的字典序。

输入输出样例

输入样例#1:
3
231
输出样例#1:
4

说明

1<=N<=9

输入的排列没有空格


题目很简单,数据范围也很小。

我们可以用next_permutation(&,&+n)暴力地解出所有情况然后判断。

在这里,主要说明的是康拓展开。(有关资料 百度博客)

嗯,很好。在看完上面的资料以后应该很清楚了。

这里是注意事项:

  1.一定在当前数的右边找比它小的数(>)。

  2.每位数(n)乘以 !(tot-n-1)其中 tot为总数位,最后一定要减一。(此时,n从0开始到结尾)

  3.最后计算结果为-比当前排列字典序小的排列,而当前排列的次序还要加一。

AC代码:

 1 //
 2 #include <bits/stdc++.h>
 3 using namespace std;
 4 typedef long long ll;
 5 #define ri register ll
 6 
 7 ll n;
 8 string s;
 9 
10 ll jc(ll a)
11 {
12     ri ans=1;
13     for(ri i=1;i<=a;i++)
14     {
15         ans*=i;
16     }
17     return ans;
18 }
19 
20 ll cantor()
21 {
22     ri end=0;
23     for(ri i=0;i<=n-1;i++)
24     {
25         ri smaller=0;
26         for(ri j=i+1;j<=n-1;j++)
27         {
28             if(s[i]>s[j]) smaller++;
29         }
30         end+= smaller*jc(n-i-1);
31     }
32     return end+1;
33 }
34 
35 signed main()
36 {
37     ios::sync_with_stdio(0),cin.tie(0);
38     cin>>n;
39     cin>>s;
40     cout<<cantor();
41     return 0;
42 }
43 //

猜你喜欢

转载自www.cnblogs.com/leprechaun-kdl/p/11030893.html