zoukankan      html  css  js  c++  java
  • ●CodeChef Sereja and Game

    题链:

    https://www.codechef.com/problems/SEAGM
    题解:

    概率dp,博弈论
    详细题解:http://www.cnblogs.com/candy99/p/6504340.html
    本体的先手胜与不胜(第一问)以及胜的概率(第二问)都是通过dp完成的,记忆化搜索实现。

    定义了一个非常妙的dp状态:(第一问)
    dp[g][c]表示当前选的数的gcd为g,且选了c个数时当前操作的人胜还是不胜。
    有了这个状态,配合预处理的cnt[g]数组(表示有cnt[g]个数为g的倍数),
    就可以很巧妙的实现dp转移:
    0.if(g==1) dp[g][c]=1
    1.if(c<cnt[g]&&!dp[g][c+1]) dp[g][c]=1
    2.if(gcd(A[i],g)!=g&&!dp[gcd(A[i],g)][c+1]) dp[g][c]=1
    第二问与第一问的方法相同,只是换成了随机情况下求概率而已。
    (如果看不太懂各种解释,建议直接服用代码。2333)


    代码:

    #include<bits/stdc++.h>
    #define MAXN 105
    using namespace std;
    int N,Case;
    int A[MAXN],cnt[MAXN];
    int opt[MAXN][MAXN];
    double rad[MAXN][MAXN];
    int gcd(int a,int b){
    	while(b^=a^=b^=a%=b);
    	return a;
    }
    int dfs_optimaly(int g,int c){
    	int &ret=opt[g][c];
    	if(g==1) ret=1;
    	if(ret!=-1) return ret;
    	ret=0;
    	if(c<cnt[g]&&!dfs_optimaly(g,c+1)) ret=1;
    	for(int i=1;i<=N;i++){
    		int gg=gcd(g,A[i]);
    		if(gg==g) continue;
    		if(!dfs_optimaly(gg,c+1)) ret=1;
    	}
    	return ret;
    }
    double dfs_randomly(int g,int c){
    	double &ret=rad[g][c];
    	if(g==1) ret=1;
    	if(ret>-0.5) return ret;
    	ret=0;
    	if(c<cnt[g]) ret+=1.0*(cnt[g]-c)/(N-c)*(1-dfs_randomly(g,c+1));
    	for(int i=1;i<=N;i++){
    		int gg=gcd(g,A[i]);
    		if(gg==g) continue;
    		ret+=1.0/(N-c)*(1-dfs_randomly(gg,c+1));
    	}
    	return ret;
    }
    int main(){
    	for(scanf("%d",&Case);Case;Case--){
    		scanf("%d",&N); int g=0;
    		for(int i=1;i<=N;i++) scanf("%d",&A[i]),g=gcd(g,A[i]);
    		if(g!=1){printf("%d %.4lf
    ",N&1,1.0*(N&1)); continue;}
    		for(int i=0;i<=100;i++){
    			cnt[i]=0;
    			for(int j=0;j<=N;j++)
    				opt[i][j]=-1,rad[i][j]=-1;
    		}
    		for(int i=2;i<=100;i++)
    			for(int j=1;j<=N;j++)
    				if(gcd(i,A[j])==i) cnt[i]++;
    		printf("%d ",dfs_optimaly(0,0));
    		printf("%.4lf
    ",dfs_randomly(0,0));
    	}
    	return 0;
    }
    

      

  • 相关阅读:
    在Windows 10 64位上编译DCMTK
    python递归解决汉诺塔
    python迭代和递归实现斐波那契
    20199302 2019-2020-2 《网络攻防实践》第4周作业
    ssh爆破
    20199302 2019-2020-2 《网络攻防实践》第3周作业
    字符串模版替换的方法MessageFormat.format(String pattern, Object ... arguments)
    Java并发编程之LinkedBlockingDeque阻塞队列详解
    理解Spring容器、BeanFactory和ApplicationContext
    Steam之两个list间交集、并集、差集
  • 原文地址:https://www.cnblogs.com/zj75211/p/8541962.html
Copyright © 2011-2022 走看看