Codeforces 678E. Another Sith Tournament(概率DP,状压)
Codeforces 678E. Another Sith Tournament
题意:
n(n<=18)个人打擂台赛,给定任意两人对决的胜负概率,比赛规则:可指定一人作为最开始的擂主,每次可指定台下的人替代失败的人上去对决,失败的人出局。问在最优决策下,第一个人留到最后的概率。
思路:
首先要观察到这一性质:一号玩家要想取得最终胜利的概率尽可能大,一定要把他安排在最后上场,只打一次。获胜概率与当前擂主以及台下的人有关,所以这个是状态,容易想到需要用二进制表示来压缩状态。
然而想到这些还是不好做,因为如果顺着逻辑正向DP是很困难的,因为每次有输和赢两种走向。因此需要倒着DP。
那么,定义dp[i][sta]:当前存活状态为sta,擂主为i的情况下,一号玩家获胜的最大概率。那么就有了这般转移式:
dp[i][sta] = max{ dp[i][sta], p[i][j] * dp[i][sta^(1<<j)] + p[j][i] * dp[j][sta^(1<<i)] }
这个转移式不是很好理解,想了比较久,觉得这样理解比较好:
对于擂主为i,存活人状态为sta的情况,枚举下一个上台的人j,对于确定的j,状态就有两种走向,i打败j或j打败i。
因此如果我们的决策是指定j上台攻擂,那么上述状态下一号玩家获胜的概率就会等于
pij(i赢j的概率) * dp[i]sta^(1<<j) + pji(i输给j的概率) * dp[j]sta^(1<<i)。
因此DP转移的顺序应该是倒着的,对于确定的存活状态,再枚举擂主以及攻擂的人,来贪心出怎么转移过去一号玩家获胜概率最大,那么倒着推到n个人都活着的时候,对擂主i枚举,即可贪出最大概率。
代码:
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<iomanip>
#include<vector>
#include<map>
#include<set>
#include<queue>
#include<cstring>
#include<cmath>
#include<functional>
#include<string>
#define dd(x) cout<<#x<<" = "<<x<<" "
#define de(x) cout<<#x<<" = "<<x<<"\n"
#define pb push_back
#define mp make_pair
#define fi first
#define se second
using namespace std;
typedef long long ll;
typedef long double ld;
typedef pair<int,int> P;
typedef priority_queue<int> BQ;
typedef priority_queue<int,vector<int>,greater<int> > SQ;
const int maxn=6e5+10,mod=1e9+7,INF=0x3f3f3f3f;
ld p[20][20];
ld dp[20][maxn];
int main()
{
int n;
cin>>n;
for (int i=0;i<n;++i)
for (int j=0;j<n;++j)
cin>>p[i][j];
dp[0][1]=1;
for (int sta=1;sta<(1<<n);++sta)
{
for (int i=0;i<n;++i)
{
if (!(sta&(1<<i)))
continue;
for (int j=0;j<n;++j)
{
if (i==j||!(sta&(1<<j)))
continue;
dp[i][sta]=max(dp[i][sta], p[i][j]*dp[i][sta^(1<<j)]+p[j][i]*dp[j][sta^(1<<i)]);
}
}
}
ld ans=-1;
for (int i=0;i<n;++i)
ans=max(ans,dp[i][(1<<n)-1]);
cout<<setprecision(10)<<ans;
return 0;
}
Codeforces 678E. Another Sith Tournament(概率DP,状压)的更多相关文章
- Educational Codeforces Round 13 E. Another Sith Tournament 概率dp+状压
题目链接: 题目 E. Another Sith Tournament time limit per test2.5 seconds memory limit per test256 megabyte ...
- codeforces 678E Another Sith Tournament 概率dp
奉上官方题解 然后直接写的记忆化搜索 #include <cstdio> #include <iostream> #include <ctime> #include ...
- 20190716NOIP模拟赛T1 礼物(概率dp+状压)
题目描述 夏川的生日就要到了.作为夏川形式上的男朋友,季堂打算给夏川买一些生 日礼物. 商店里一共有种礼物.夏川每得到一种礼物,就会获得相应喜悦值Wi(每种 礼物的喜悦值不能重复获得). 每次,店员会 ...
- Codeforces 678E Another Sith Tournament 状压DP
题意: 有\(n(n \leq 18)\)个人打擂台赛,编号从\(1\)到\(n\),主角是\(1\)号. 一开始主角先选一个擂主,和一个打擂的人. 两个人之中胜的人留下来当擂主等主角决定下一个人打擂 ...
- Codeforces 678E(Another Sith Tournament)
题目链接:传送门 题目大意:有n个人决斗(n<=18),每两个人之间都有一定几率杀死对方,一次进行一次决斗,胜利者成为擂主继续接受决斗直到只剩下一个人,你是一号,问你最大有多大几率存活到最后. ...
- hdu 4336 概率dp + 状压
hdu 4336 小吃包装袋里面有随机赠送一些有趣的卡片,如今你想收集齐 N 张卡片.每张卡片在食品包装袋里出现的概率是p[i] ( Σp[i] <= 1 ), 问你收集全部卡片所需购买的食品数 ...
- HDU4336 Card Collector (概率dp+状压dp)
http://acm.hdu.edu.cn/showproblem.php?pid=4336 题意:有n种卡片,一个包里会包含至多一张卡片,第i种卡片在某个包中出现的次数为pi,问将所有种类的卡片集齐 ...
- SCUT - 254 - 欧洲爆破 - 概率dp - 状压dp
https://scut.online/p/254 思路很清晰,写起来很恶心. #include<bits/stdc++.h> using namespace std; #define l ...
- 【HDU】4352 XHXJ's LIS(数位dp+状压)
题目 传送门:QWQ 分析 数位dp 状压一下现在的$ O(nlogn) $的$ LIS $的二分数组 数据小,所以更新时直接暴力不用二分了. 代码 #include <bits/stdc++. ...
随机推荐
- Docker 启动SQLServer
1.运行这个命令 docker run -d -e SA_PASSWORD=Docker123 -e SQLSERVER_DATABASE=qgb -e SQLSERVER_USER=sa -e ...
- 某康x电视去广告
开启adb 信源选择进入模拟电视 然后按菜单键输入2008 找到其他选项,进去把adb root打开 删除对应广告视频(短暂方法) 可以下载tvbox,利用文件管理功能 进入/data/misc/ko ...
- python之random库的使用以及程序的异常处理
1.random库的使用: random库是使用随机数的Python标准库从概率论角度来说,随机数是随机产生的数据(比如抛硬币),但时计算机是不可能产生随机值,真正的随机数也是在特定条件下产生的确定值 ...
- octave 笔记
1. 画函数 >> x = [-4:0.5:6] >> y = x.^2 - x - 6 >> plot(y)
- .NET 使用事物调用存储过程
using System; using System.Collections.Generic; using System.Configuration; using System.Data; using ...
- eclipse svn 插件离线安装后connector获取不到的问题解决
最近换了一家公司,写代码的电脑不给外网,所以各种麻烦的问题就来了,这里就说一下eclipse 安装SVN插件的一个小问题,虽说是小问题,但也折腾了我好几个小时,当然也可以不用这个插件,直接安装SVN客 ...
- idea控制台乱码修改
我的idea当前版本是2019.2.2 试了很多,只有这个有效果 工具类→HELP→Edit Custom VM OPtions中加 -Dfile.encoding=utf-8 然后重启IDEA 这个 ...
- 【SpringBoot】入门程序和机制分析
一.初建项目 首先要导入SpringBoot的Maven依赖 <!-- Inherit defaults from Spring Boot --> <!-- 这是SpringBoot ...
- 【atcoder】GP 2 [agc036C]
题目传送门:https://atcoder.jp/contests/agc036/tasks/agc036_c 题目大意:给你一个长度为$N$初始全0的序列,每次操作你可以找两个不同的元素,一个自增1 ...
- 图像处理---《在图片上打印文字 windows+GDI+TrueType字体》
图像处理---<在图片上打印文字 windows+GDI+TrueType字体> 刚开始使用的是putText()函数做,缺陷是只能显示非中文: 接着,看大多数推荐Freetype库来做 ...