CSU - 1917 There is no SSR (概率dp+矩阵优化)

In the ACMers of CSU, Zihao LI is a fan of yinyangshi. However, he has African blood in his veins. One day, he collected many charms to conjure Shikigami, which Chinese called shishen. Shishen has three levels:SSR, SR, R, and SSR is a rarity, R is ordinary, SR is between them. For most people, they can get one SSR, nineteen SR, and eighty R when he uses 100 charms. But Mr.Li is different. He can’t get SSR for his African blood...So, the score of luck for poor Mr.Li depend to the number of SR he gets in succession. Now, we know the probability of Mr.Li to conjure R, SR and the sum is equal to one. We want to know the probability of Mr.Li getting n SR in succession, which means he is lucky.

Input

There are many tests. Each case has two floats represent the probability of R, SR(0 < p1, p2 < 1)and two integer n (0 < n <= 100)as described above and m (0 < m <=1e7), the numbers of charms.

Output

For each test case, print a single float on its own line denoting the probability of Mr.Li getting n SR in succession. The answer should be around to the 1e-6.

Sample Input

0.0 1.0 1 2
1.0 0.0 1 2
0.5 0.5 1 2

Sample Output

1.000000
0.000000
0.750000

题意:阴阳师抽奖,得到R的概率为p,得到SR的概率为1-p,求抽m次奖连续获得n个SR的概率。

思路:我们可以反过来考虑,求出不会连续得到n个SR的概率,这个问题我们可以通过简单dp递推得到【dp[i]为抽i次奖不会连续得到n个SR的概率】:

但是由于m太大,因此我们没法线性递归,而由该递推式的特点,我们发现可以通过矩阵优化,并通过矩阵快速幂的方式在n^3logm的复杂度内解决。

#include<set>
#include<map>
#include<stack>
#include<queue>
#include<vector>
#include<string>
#include<math.h>
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#include<functional>
using namespace std;
#define ll long long
#define maxn 500050
struct mat{
	int n,m;
	double a[15][15];
	mat(int n,int m):n(n),m(m){}
	mat(){}
	void init(){
		for(int i=0;i<n;i++)
			for(int j=0;j<m;j++)
				a[i][j]=0;
	}
}a;
double po[15],p,q;
int n,m;
mat mul(mat a,mat b){
	mat c(a.n,b.m);
	c.init();
	for(int i=0;i<c.n;i++)
		for(int j=0;j<c.m;j++)
			for(int k=0;k<a.m;k++)
				c.a[i][j]+=a.a[i][k]*b.a[k][j];
	return c;
}
double matPow(int n){ 
	mat b(a.n,1); b.init();
	for(int i=0;i<a.n;i++)
		b.a[i][0]=1;
	while(n){
		if(n&1)
			b=mul(a,b);
		a=mul(a,a);
		n/=2;
	}
	return b.a[0][0];
}
int main(void){
	while(scanf("%lf%lf%d%d",&p,&q,&n,&m)!=EOF){
		if(q==0){
			printf("0.000000\n");
			continue;
		}
		po[0]=1;
		a=mat(n,n);
		a.init();
		for(int i=1;i<=n;i++)
			po[i]=po[i-1]*q;
		for(int i=n-1;i>=0;i--)
			a.a[0][i]=po[i]*p;
		for(int i=1;i<n;i++)
			a.a[i][i-1]=1.0;
		printf("%f\n",1.0-matPow(m-n+1));
	}
	return 0;
}

 

1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。、可私 6信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 、可私信6博主看论文后选择购买源代码。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值