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 ...
随机推荐
- devicemaps_init(mdesc)
devicemaps_init的参数为machine_desc结构体.以s3c6410为例,在arch/arm/mach-s3c64xx/mach-smdk6410.c中使用上述宏声明machine_ ...
- oracle 事务 锁机制
原文地址:http://www.cnblogs.com/quanweiru/archive/2013/05/24/3097367.html 本课内容属于Oracle高级课程范畴,内容略微偏向理论性,但 ...
- HDU 4005 The war 双连通分量 缩点
题意: 有一个边带权的无向图,敌人可以任意在图中加一条边,然后你可以选择删除任意一条边使得图不连通,费用为被删除的边的权值. 求敌人在最优的情况下,使图不连通的最小费用. 分析: 首先求出边双连通分量 ...
- 03014_EL技术
1.EL表达式概述 EL(Express Language)表达式可以嵌入在jsp页面内部,减少jsp脚本的编写,EL出现的目的是要替代jsp页面中脚本的编写. 2.EL从域中取出数据(EL最重要的作 ...
- 手机端sticker布局,底部按钮在屏幕底部
<template> <div class="product-detail-container"> <div class="detail&q ...
- loj2090 「ZJOI2016」旅行者
分治+最短路,很套路的 #include <algorithm> #include <iostream> #include <cstring> #include & ...
- 设计模式之第20章-访问者模式(Java实现)
设计模式之第20章-访问者模式(Java实现) “嘿,你脸好红啊.”“精神焕发.”“怎么又黄了?”“怕冷,涂的,涂的,蜡.”“身上还有酒味,露馅了吧,原来是喝酒喝的啊.”“嘿嘿,让,让你发现了,今天来 ...
- 53、listview、expandableListview如何选中时保持高亮?
一.listView被选中后保持高亮 70down voteaccepted To hold the color of listview item when you press it, include ...
- 使用 Item,ItemManager 在 XNA 中创建物品和道具(十六)
平方已经开发了一些 Windows Phone 上的一些游戏,算不上什么技术大牛.在这里分享一下经验,仅为了和各位朋友交流经验.平方会逐步将自己编写的类上传到托管项目中,没有什么好名字,就叫 WPXN ...
- HDU3977 Evil teacher 求fib数列模p的最小循环节
In the math class, the evil teacher gave you one unprecedented problem! Here f(n) is the n-th fibona ...