• Luogu2059 [JLOI2013]卡牌游戏


    (My Blog)

    Description

    link

    (n(nle50)) 个人坐在一圈,有 (m(mle 50)) 张牌,每个人每轮随机抽一张,数字是(k)

    以该人为第一个,顺时针第(k) 个出局

    求每个人在进行完 (n-1) 轮后胜利的概率

    Solution

    先定义状态:(f_{i,j})(i) 个人做游戏,第 (j) 个最终获胜的概率

    起始态:(f_{1,1}=1) (含义)

    目标态:(f_{n,p},ple n)

    转移:

    [f_{i,j}=sum_{k=1}^m f_{i-1,j-d[k]} ]

    这里(d_k) 是牌上的数字,(j-d_k)需要考虑是负数的情况(加个 (i) 就行了)

    讲讲想法:

    是个逆推的思想,正推的做法……

    我们看第 (j) 个人拿到一张牌能干掉谁,

    那个人再如果没有这一轮是赢的,所以 (j) 干掉了他也就赢了

    本题就完结了

    Code

    #include<bits/stdc++.h>
    using namespace std;
    #define int long long
    namespace yspm{
    	inline int read()
    	{
    		int res=0,f=1; char k;
    		while(!isdigit(k=getchar())) if(k=='-') f=-1;
    		while(isdigit(k)) res=res*10+k-'0',k=getchar();
    		return res*f;
    	}
    	const int N=101;
    	double f[N][N];
    	int n,m,a[N];
    	signed main()
    	{
    		n=read(); m=read();
    		for(int i=1;i<=m;++i) a[i]=read();
    		f[1][1]=1;
    		for(int i=2;i<=n;++i)
    		{
    			for(int j=1;j<=i;++j)
    			{
    				for(int k=1;k<=m;++k)
    				{
    					int t=a[k]%i; if(!t) t=i;
    					if(t>j) f[i][j]+=f[i-1][i-t+j]/m;
    					if(t<j) f[i][j]+=f[i-1][j-t]/m;
    				}
    			}
    		}
    		for(int i=1;i<=n;++i) printf("%.2lf\% ",f[n][i]*100); puts("");
    		return 0;
    	}
    }
    signed main(){return yspm::main();}
    

    Review

    对于有些可 (dfs) 的题目,可以考虑用一下记忆化或者类似从结果开始记录答案的思想

    感觉这个题是个好题,但是百分号输出就有时候不太地道

  • 相关阅读:
    python之元组
    python之dict
    python之list
    python之str字符串
    python之for循环
    Python的基本语法2
    Python的基本语法1
    初识python
    JS获取当天是周几
    EXCLE导入数据库
  • 原文地址:https://www.cnblogs.com/yspm/p/12829931.html
Copyright © 2020-2023  润新知