CodeChef Sereja and Game [DP 概率 博弈论]
https://www.codechef.com/problems/SEAGM
题意:
n个数(可能存在相同的数),双方轮流取数。如果在一方选取之后,所有
已选取数字的GCD变为1,则此方输。
问:
1 若双方均采取最优策略,先手是否必胜?
2 若双方随机取数,先手获胜的概率为多少?
$n,ai \le 100$
状态比较难想,核心是找到一个划分阶段的顺序:根据$GCD$划分阶段
$GCD$是只会减小不会增加的
课件上的状态是$f[i][j]$表示当前$GCD$为$i$,没选的$i$的倍数有$j$个,感觉有点奇怪...
看了一下官方题解,意识到只要记录$j$为当前已经选的有$j$个就好了,已经选的一定是$i$的倍数,这样就和其他的状态比较像了
转移还是比较好想的
$1.\ f[i][j] \rightarrow f[i][j+1]\ :\ j<mult[i]$
$2.\ f[i][j] \rightarrow f[gcd(i,k)][j+1]\ :\ 1 \le gcd(i,k) \le i$
记忆化搜索倒推就行了
PS:给$gcd$加上记忆化之后$0s$就跑过去了....
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long long ll;
const int N=;
const double eps=1e-;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-;c=getchar();}
while(c>=''&&c<=''){x=x*+c-'';c=getchar();}
return x*f;
}
int n,a[N];
int g[N][N];
int gcd(int a,int b){return g[a][b] ? g[a][b] : g[a][b]=(b==?a:gcd(b,a%b));}
//int gcd(int a,int b){return b==0?a:gcd(b,a%b);}
int f[N][N];
double p[N][N];
bool dfsWin(int u,int c){//printf("dfsWin %d %d\n",u,c);
int &re=f[u][c];
if(c==n) re=;//has chosen all
if(u==) re=;//win
if(re!=-) return re; re=;
int mult=;
for(int i=;i<=n;i++) if(gcd(u,a[i])==u) mult++;
if(c<mult&&!dfsWin(u,c+)) re=;
else{
for(int i=;i<=n;i++)
if(gcd(u,a[i])>&&gcd(u,a[i])!=u)
if(!dfsWin(gcd(u,a[i]),c+)) {re=;break;}
}
return re;
}
double dfsPro(int u,int c){//printf("dfsPro %d %d\n",u,c);
double &re=p[u][c];
if(c==n) re=0.0;
if(u==) re=1.0;
if(re>-0.9) return re; re=0.0;
int mult=;
for(int i=;i<=n;i++) if(gcd(u,a[i])==u) mult++;
if(c<mult) re+= (double)(mult-c) / (n-c) * (-dfsPro(u,c+));
for(int i=;i<=n;i++)
if(gcd(u,a[i])>&&gcd(u,a[i])!=u)
re+=(double) / (n-c) *(-dfsPro(gcd(u,a[i]),c+));
if(abs(re)<eps) re=;
return re;
}
int main(){
freopen("in","r",stdin);
int T=read();
while(T--){
n=read(); int g=;
for(int i=;i<=n;i++) a[i]=read(),g=gcd(a[i],g);
if(g>){printf("%d %.4lf\n",n&,double(n&));continue;} for(int i=;i<N;i++) for(int j=;j<N;j++) f[i][j]=-,p[i][j]=-1.0;
int flag=dfsWin(,);
printf("%d ",flag); double prob=dfsPro(,);
printf("%.4lf\n",prob);
}
}
CodeChef Sereja and Game [DP 概率 博弈论]的更多相关文章
- ●CodeChef Sereja and Game
题链: https://www.codechef.com/problems/SEAGM题解: 概率dp,博弈论 详细题解:http://www.cnblogs.com/candy99/p/650434 ...
- UVA 11427 Expect the Expected(DP+概率)
链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=35396 [思路] DP+概率 见白书. [代码] #include&l ...
- tyvj P1864 [Poetize I]守卫者的挑战(DP+概率)
P1864 [Poetize I]守卫者的挑战 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 打开了黑魔法师Vani的大门,队员们在迷宫般的路上漫无目的地搜 ...
- [LnOI2019]加特林轮盘赌(DP,概率期望)
[LnOI2019]加特林轮盘赌(DP,概率期望) 题目链接 题解: 首先特判掉\(p=0/1\)的情况... 先考虑如果\(k=1\)怎么做到\(n^2\)的时间复杂度 设\(f[i]\)表示有\( ...
- poj 2096 Collecting Bugs(期望 dp 概率 推导 分类讨论)
Description Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other ...
- BZOJ 3566: [SHOI2014]概率充电器 [树形DP 概率]
3566: [SHOI2014]概率充电器 题意:一棵树,每个点\(q[i]\)的概率直接充电,每条边\(p[i]\)的概率导电,电可以沿边传递使其他点间接充电.求进入充电状态的点期望个数 糖教题解传 ...
- BZOJ 1415: [Noi2005]聪聪和可可 [DP 概率]
传送门 题意:小兔子乖乖~~~ 题意·真:无向图吗,聪抓可,每个时间聪先走可后走,聪一次可以走两步,朝着里可最近且点编号最小的方向:可一次只一步,等概率走向相邻的点或不走 求聪抓住可的期望时间 和游走 ...
- Codeforces1097D. Makoto and a Blackboard(数论+dp+概率期望)
题目链接:传送门 题目大意: 给出一个整数n写在黑板上,每次操作会将黑板上的数(初始值为n)等概率随机替换成它的因子. 问k次操作之后,留在黑板上的数的期望. 要求结果对109+7取模,若结果不是整数 ...
- Codeforces 425E Sereja and Sets dp
Sereja and Sets 我们先考虑对于一堆线段我们怎么求最大的不相交的线段数量. 我们先按 r 排序, 然后能选就选. 所以我们能想到我们用$dp[ i ][ j ]$表示已经选了 i 个线段 ...
随机推荐
- 在虚拟机(VMware)中安装Linux CentOS 6.4系统(图解) 转
一.下载最新版本Linux CentOS 1.打开官网地址:http://www.centos.org/,点击Downloads->Mirrors 2.点击CentOS ...
- vuex的使用
vue现在越来越火,不单单可以写简单的小项目,也可以写大中型的项目.但是项目大了,项目之间的数据传递就会变得复杂,那么问题来了?在一个大型项目中,多个组件要公用同一个或多个数据,我们如何保证每个组件获 ...
- Yourphp是一款完全开源免费的.核心采用了Thinkphp框架
Yourphp企业网站管理系统,是一款完全开源免费的PHP+MYSQL系统.核心采用了Thinkphp框架,同时也作为开源软件发布.集众多开源项目于一身的特点,使本系统从安全,效率,易用及可扩展性上更 ...
- sublime text3怎么批量查找替换文件夹中的字符
在编写代码的时候,往往有些代码是重复的,但是如果要改一处代码,其他的地方也要改.那么怎么批量修改呢?下面小编就以sublime text3为例来讲解一下sublime text3怎么批量查找替换文件夹 ...
- Struts2与Ajax数据交互
写在前面: ajax请求在项目中常常使用,今天就平时掌握的总结一下,关于使用ajax请求到Struts2中的action时,前台页面与后台action之间的数据传递交互问题. 这里我主要记录下自己所掌 ...
- Java进阶篇(三)——Java集合类
集合可以看作一个容器,集合中的对象可以很容易存放到集合中,也很容易将其从集合中取出来,还可以按一定的顺序摆放.Java中提供了不同的集合类,这些类具有不同的存储对象的方式,并提供了相应的方法方便用户对 ...
- Java Draw
简单绘画 直线 矩形 圆 根据矩阵画图 package com.zhoudm; import java.awt.*; import javax.swing.*; public class Draw e ...
- JAVA正则表达式 Pattern和Matcher
java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包. 1.简介: java.util.regex是一个用正则表达式所订制的模式来对字符串进行匹配工作的类库包. ...
- 一步步使用BMC Atrium Orchestrator Vmware Infrastructure Event Monitor
本教程将一步步演示怎么使用BMC Atrium Orchestrator (BAO) Vmware Infrastructure Event Monitor来监控VSphere Webservice的 ...
- CentOS如何把deb转为rpm
说明:可以转换,但不一定可用,可以根据报错提示,安装需要的依赖. 1 安装alien工具,下载地址http://ftp.de.debian.org/debian/pool/main/a/alien/ ...