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 ...
随机推荐
- Codeforces Round #464 (Div. 2) D. Love Rescue
D. Love Rescue time limit per test2 seconds memory limit per test256 megabytes Problem Description V ...
- 动态规划:HDU1059-Dividing(多重背包问题的二进制优化)
Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) Total S ...
- Spark性能优化:开发调优篇
1.前言 在大数据计算领域,Spark已经成为了越来越流行.越来越受欢迎的计算平台之一.Spark的功能涵盖了大数据领域的离线批处理.SQL类处理.流式/实时计算.机器学习.图计算等各种不同类型的计算 ...
- loj2057 「TJOI / HEOI2016」游戏
记横联通是一块横着的没有硬石头的地,把他们编号.竖联通同理. 对于一个空地,将其横联通编号和竖联通编号连边,二分图匹配,最大匹配为答案. #include <iostream> #incl ...
- CSU-2049 象棋
CSU-2049 象棋 Description 車是中国象棋中的一种棋子,它能攻击同一行或同一列中没有其他棋子阻隔的棋子.一天,小度在棋盘上摆起了许多車--他想知道,在一共N×M个点的矩形棋盘中摆最多 ...
- 三种框架对比react vue 和Angular对比
https://blog.csdn.net/runOnWay/article/details/80103880 angular 优点 背靠谷歌 使用typescript 便于后端人员开发上手 完整 不 ...
- Spring框架annotation实现IOC介绍
Spring学习笔记(三) 续Spring 学习笔记(二)之后,对Spring框架的annotation实现方法进行整理 本文目录 @Autowire 1 @Autowire+@Qualifier t ...
- 201621123034 《Java程序设计》第4周学习总结
Week04-面向对象设计与继承 1. 本周学习总结 1.1 写出你认为本周学习中比较重要的知识点关键词 答:对象.重载.继承.多态 1.2 尝试使用思维导图将这些关键词组织起来.注:思维导图一般不需 ...
- MySQL Innodb表导致死锁日志情况分析与归纳
发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志 案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时 ...
- docker (centOS 7) 使用笔记6 - skydns
skydns被用于kubenets作为DNS服务.本次测试是单独使用skydns作为DNS服务器,且作为loadbalance使用. 前提:需要先安装配置etcd服务 (在前面的文章里,已经安装部署了 ...