Codeforces Gym10081 A.Arcade Game-康托展开、全排列、组合数变成递推的思想
最近做到好多概率,组合数,全排列的题目,本咸鱼不会啊,我概率论都挂科了。。。
这个题学到了一个康托展开,有点用,瞎写一下。。。
康托展开:
适用对象:没有重复元素的全排列。
直接上题目:
Arcade mall is a new modern mall. It has a new hammer game called "Arcade Game". In this game you're presented with a number n which is hanged on a wall on top of a long vertical tube, at the bottom of the tube there is a button that you should hit with your hammer.
When you hit the button with all your force (as you always do), a ball is pushed all over the tube and hit the number n. The number n flies in the air and it's digits fall back in any random permutation with uniform probability.
If the new number formed is less than or equal to the previous number, the game ends and you lose what ever the new number is. Otherwise (if the number is greater than the previous number), you are still in the game and you should hit the button again.
You win if the new number formed is greater than the previous number and it is equal to the greatest possible permutation number.
Can you compute the probability of winning?
Input
The first line of the input contains the number of test cases T. Following that there are T lines represents T test cases. In each line, there is a single integer (1 ≤ n ≤ 109) the target number. The digits of n are all unique, which means that any 2 digits of n are different.
Output
For each test case, print one line containing the answer. Print the answer rounded to exactly 9 decimal digits.
Example
3
952
925
592
0.000000000
0.166666667
0.194444444
Note
In the first test case, the answer is 0 because 952 is greater than all 2,5 and 9 permutations so you can't win, whatever you do.
In the second test case, the answer is 0.166666667 because you may win by getting number 952 with probability 1/6.
In the third test case the answer is 0.194444444 because you may win by getting number 952 in round1 with probability 1/6 or you can win by getting number 925 in round 1 and then 952 in round 2 with probability 1/6 * 1/6.
这个题就是找出来之后求概率,这里求概率是把符合条件的都加进去,假设10个数,每个数被跳到的概率都是1/10,为P。
假设你要求的是排名第5,那么排名第5的跳到排名第1的有很多种跳法。可以直接跳到第一大,也可以跳2步,也可以跳3步,也可以跳4步。因为最后都是要跳到最大的,所以只求中间的步数的概率就可以,所以就是排列组合的问题,就是P*C(1,1)+P^2*C(1,3)+P^3*C(2,3)+P^4*C(3,3)。但是如果按组合数写的话,会超时,这里把组合数优化一下,写成递推就可以了,极限操作最大就是10^9,而不是(10^9+1)*10^9/2次操作。就是从n^2d的操作变成n的操作,但是递推怎么想呢。
抽抽一下,发现,跳1步为0,从第2大跳到第1大赢的概率就是Q1=P,从第3大开始跳获胜的概率就是Q2=P+P*Q1=Q1*(1+P),从第4大开始跳获胜的概率就是Q3=P+P*Q2+P*Q1=Q2*(1+P),从第5大开始跳获胜的概率就是Q4=P+P*Q3+P*Q2+P*Q1=Q3*(1+P)。写的乱七八糟,不知道能不能看懂。。。
代码:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=1e7+;
typedef long long ll;
ll fac[N];
bool cmp(char a,char b){
return a>b;
}
void factorial(){ //阶乘
fac[]=;
for(int i=;i<;i++){
fac[i]=fac[i-]*i;
}
}
int cantor(char s[],int n){ //康托展开
int cnt,sum;
sum=;
factorial();
for (int i=;i<n;++i){
cnt=;
for(int j=i+;j<n;++j)
if(s[j]<s[i])++cnt;
sum+=cnt*fac[n-i-];
}
return sum;
}
char s[N];
double ans[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
memset(s,,sizeof(s));
scanf("%s",s);
int len=strlen(s);
int num1=cantor(s,len)+; //该数的排名,第几大
//cout<<num1<<endl;
sort(s,s+len,cmp);
int num2=cantor(s,len)+; //最大的数的排名就是全排列一共多少个数
//cout<<num2<<endl;
double gailv=1.0/num2;
//cout<<gailv<<endl;
//cout<<num2-num1<<endl;
ans[]=;ans[]=gailv;
for(int i=;i<=num2-num1;i++){ //递推
ans[i]=ans[i-]*(+gailv);
}
printf("%.9f\n",ans[num2-num1]);
}
return ;
}
太智障了,好蠢啊。。。
Codeforces Gym10081 A.Arcade Game-康托展开、全排列、组合数变成递推的思想的更多相关文章
- Codeforces Round #526 C - The Fair Nut and String /// 组合递推
题目大意: 给定原字符序列 找出其中所有子序列满足 1.序列内字符都为a 2.若有两个以上的字符 则相邻两个字符在原序列中两者之间存在字符b 的数量 将整个字符序列用b分开 此时再得到每个b之间a的数 ...
- CF思维联系–CodeForces - 223 C Partial Sums(组合数学的先线性递推)
ACM思维题训练集合 You've got an array a, consisting of n integers. The array elements are indexed from 1 to ...
- 转换地图 (康托展开+预处理+BFS)
Problem Description 在小白成功的通过了第一轮面试后,他来到了第二轮面试.面试的题目有点难度了,为了考核你的思维能量,面试官给你一副(2x4)的初态地图,然后在给你一副(2x4)的终 ...
- 用康托展开实现全排列(STL、itertools)
康拓展开: $X=a_n*(n-1)!+a_{n-1}*(n-2)!+\ldots +a_2*1!+a_1*0!$ X=an*(n-1)!+an-1*(n-2)!+...+ai*(i-1)!+...+ ...
- OJ 1188 全排列---康托展开
题目描述 求n的从小到大第m个全排列(n≤20). 输入 n和m 输出 输出第m个全排列,两个数之间有一空格. 样例输入 3 2 样例输出 1 3 2 #include<cstdio> # ...
- LightOJ1060 nth Permutation(不重复全排列+逆康托展开)
一年多前遇到差不多的题目http://acm.fafu.edu.cn/problem.php?id=1427. 一开始我还用搜索..后来那时意外找到一个不重复全排列的计算公式:M!/(N1!*N2!* ...
- 康托展开:对全排列的HASH和还原,判断搜索中的某个排列是否出现过
题目:http://acm.hrbust.edu.cn/index.php?m=ProblemSet&a=showProblem&problem_id=2297 前置技能:(千万注意是 ...
- UVA11525 Permutation[康托展开 树状数组求第k小值]
UVA - 11525 Permutation 题意:输出1~n的所有排列,字典序大小第∑k1Si∗(K−i)!个 学了好多知识 1.康托展开 X=a[n]*(n-1)!+a[n-1]*(n-2)!+ ...
- leetcode 60. Permutation Sequence(康托展开)
描述: The set [1,2,3,…,n] contains a total of n! unique permutations. By listing and labeling all of t ...
随机推荐
- Bubblesort冒泡算法
最简单的算法,大家都知道两层for循环,中间加一个过渡用来交换数据 小例子: package com.neuedu.algorithm;//算法 public class Bubblesort { / ...
- CMSIS-DAP仿真器_学习(转载)
先给大家普及一下,哈哈.CMSIS-DAP仿真器,是ARM官方做的开源仿真器,没有版权,自由制作.官方给的源代码,使用的是NXP的单片机LPC4320做的.这个源代码,只要你安装了KEIL5,就可以找 ...
- VBA连接MySQL数据库以及ODBC的配置(ODBC版本和MySQL版本如果不匹配会出现驱动和应用程序的错误)
db_connected = False '获取数据库连接设置dsn_name = Trim(Worksheets("加载策略").Cells(2, 5).Value) ---- ...
- webpack + babel + vue 环境设置
npm i webpack --save-dev npm install style-loader css-loader url-loader babel-loader sass-loader fil ...
- Java8_Lambda表达式
从2014年java8发布到现在已经有几个年头了,现在java11都发布了.公司最近把服务器环境重新搭建了一遍,jdk版本也从7换成了8,终于可以在代码里面写Lambda表达式了.作为 ...
- C#+VisionPro连接相机获取图像的两种方式
两种比较常用的方式. C#直接连接相机获取图像(GIGE) 在获取图像前,需要先创建一个相机对象,再使用这个相机对象的Acquire方法拍摄照片. ICogAcqFifo macqfifo;//定义相 ...
- Leetcode 522.最长特殊序列II
最长特殊序列II 给定字符串列表,你需要从它们中找出最长的特殊序列.最长特殊序列定义如下:该序列为某字符串独有的最长子序列(即不能是其他字符串的子序列). 子序列可以通过删去字符串中的某些字符实现,但 ...
- 关于caffe 是如何卷积的一点总结
最近,在看caffe源码时,偶然在网上看到一个问题?觉得挺有意思,于是,仔细的查了相关资料,并将总结写在这里,供大家迷惑时,起到一点启示作用吧. 问题的题目是CNN中的一个卷积层输入64个通道的特征子 ...
- Ubuntu系统设置中心不见了
sudo apt-get install unity-control-center 执行安装上述即可 原因是因为在安装搜狗输入法的时候卸载了ibuts与系统控制中心
- [国家集训队][bzoj2120] 数颜色 [带修改莫队]
题面: 传送门 思路: 这道题和SDOI2009的HH的项链很像,只是多了一个修改 模板套上去呀 莫队学习请戳这里:莫队 Code: #include<iostream> #include ...