Description

This is back in the Wild West where everybody is fighting everybody. In particular, there are n cowboys, each with a revolver. These are rather civilized cowboys, so they have decided to take turns firing their guns until only one is left standing. Each of them has a given probability of hitting his target, and they all know each other’s probability. Furthermore, they are geniuses and always know which person to aim at in order to maximize their winning chance, so they are indeed peculiar cowboys. If there are several equally good targets, one of those will be chosen at random. Note that a cowboy’s code of ethics forces him to do his best at killing one of his opponents, even if intentionally missing would have increased his odds (yes, this can happen!)

Input

On the first line of the input is a single positive integer t, telling the number of test cases to follow. Each case consists of one line with an integer 2 ≤ n ≤ 13 giving the number of cowboys, followed by n positive integers giving hit percentages for the cowboys in the order of their turns.

Output

For each test case, output one line with the percent probabilities for each of them surviving, in the same order as the input. The numbers should be separated by a space and be correctly rounded to two decimal places.

题目大意:n个枪手,均有一个命中率,从第一位开始,每次下一位开枪射击一个人。问每个人的生存率是多少,枪手总会朝着对自己最有利的人开枪,但一定要开枪,不能向自己开枪,如果有多个最有利的人,随机向其中一个开枪。

思路:O(n^4*2^n)水过去的……所以思路就不怎么讲了……(next每次算会TLE,先预处理出来依然TLE……)现在实在想不到什么好方法先这样吧……

PS:贴一下做题时候的草稿

b[i]为i命中的胜率
a[i]为i不命中的胜率
p[i]为i的命中率
q[i]为1-p[i]
a[i] = p[i+1] * b[i+1] + q[i+1] * a[i+1]
= p[i+1] * b[i+1] + q[i+1] * (p[i+2] * b[i+2] + q[i+2] * a[i+2])
= p[i+1] * b[i+1] + q[i+1] * p[i+2] * b[i+2] + q[i+1] * q[i+2] * a[i+2]
= p[i+1] * b[i+1] + q[i+1] * p[i+2] * b[i+2] + ……
+ pro{q[i+1] .. q[i-1]} * p[i] * b[i] + pro{q[i+1] .. q[i]} * a[i]
a[i] = (p[i+1] * b[i+1] + q[i+1] * p[i+2] * b[i+2] + ……
+ pro{q[i+1] .. q[i-1]} * p[i] * b[i]) / (1 - pro{q[i+1] .. q[i]})

代码(2641MS):

 #include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
typedef long long LL; const int MAXN = ;
const double EPS = 1e-; int T, n;
double dp[MAXN][( << MAXN) + ][MAXN];
double p[MAXN]; inline int sgn(double x) {
return (x > EPS) - (x < -EPS);
} int Tnext[ << MAXN][MAXN]; inline int next(int state, int x) {
if(Tnext[state][x] != -) return Tnext[state][x];
int ret = x;
while(true) {
if(++ret == n) ret = ;
if(state & ( << ret)) break;
}
return Tnext[state][x] = ret;
} inline int count(int state) {
int ret = ;
while(state) {
ret += state & ;
state >>= ;
}
return ret;
} int c[MAXN][MAXN];
double b[MAXN][MAXN], maxb[MAXN]; void dfs(int state, int cur) {
if(dp[cur][state][] != -) return ;
if(count(state) == ) {
for(int i = ; i < n; ++i) dp[cur][state][i] = (i == cur);
return ;
} for(int i = ; i < n; ++i) {
if((state & ( << i)) == ) continue;
for(int tar = next(state, i); tar != i; tar = next(state, tar)) {
int newState = state ^ ( << tar), nx = next(newState, i);
dfs(newState, nx);
}
} for(int i = ; i < n; ++i)
for(int j = ; j < n; ++j) b[i][j] = c[i][j] = ;
for(int i = ; i < n; ++i) maxb[i] = ; for(int i = ; i < n; ++i) {
if((state & ( << i)) == ) continue;
for(int tar = next(state, i); tar != i; tar = next(state, tar)) {
int newState = state ^ ( << tar), nx = next(newState, i);
maxb[i] = max(maxb[i], dp[nx][newState][i]);
}
for(int tar = next(state, i); tar != i; tar = next(state, tar)) {
int newState = state ^ ( << tar), nx = next(newState, i);
if(sgn(maxb[i] - dp[nx][newState][i]) == ) {
for(int k = ; k < n; ++k) {
++c[i][k];
b[i][k] += dp[nx][newState][k];
}
}
}
for(int k = ; k < n; ++k) b[i][k] /= c[i][k];
} for(int k = ; k < n; ++k) dp[cur][state][k] = p[cur] * b[cur][k]; for(int k = ; k < n; ++k) {
if((state & ( << k)) == ) continue;
int now = cur;
double tmp = , sum = ;
do {
now = next(state, now);
sum += tmp * p[now] * b[now][k];
tmp *= ( - p[now]);
} while(cur != now);
dp[cur][state][k] += sum / ( - tmp) * ( - p[cur]);
}
} void solve() {
dfs(( << n) - , );
for(int i = ; i < n - ; ++i) printf("%.2f ", * dp[][( << n) - ][i]);
printf("%.2f\n", * dp[][( << n) - ][n - ]);
} int main() {
memset(Tnext, -, sizeof(Tnext));
scanf("%d", &T);
while(T--) {
scanf("%d", &n);
for(int i = ; i < n; ++i) scanf("%lf", &p[i]), p[i] /= ;
for(int i = ; i < n; ++i)
for(int j = ; j < ( << n); ++j) dp[i][j][] = -;
solve();
}
}

POJ 3028 Shoot-out(概率DP)的更多相关文章

  1. poj 3071 Football(概率dp)

    id=3071">http://poj.org/problem? id=3071 大致题意:有2^n个足球队分成n组打比赛.给出一个矩阵a[][],a[i][j]表示i队赢得j队的概率 ...

  2. POJ 2096 Collecting Bugs (概率DP,求期望)

    Ivan is fond of collecting. Unlike other people who collect post stamps, coins or other material stu ...

  3. POJ 2096 Collecting Bugs (概率DP)

    题意:给定 n 类bug,和 s 个子系统,每天可以找出一个bug,求找出 n 类型的bug,并且 s 个都至少有一个的期望是多少. 析:应该是一个很简单的概率DP,dp[i][j] 表示已经从 j ...

  4. poj 2096 Collecting Bugs (概率dp 天数期望)

    题目链接 题意: 一个人受雇于某公司要找出某个软件的bugs和subcomponents,这个软件一共有n个bugs和s个subcomponents,每次他都能同时随机发现1个bug和1个subcom ...

  5. poj 2096 Collecting Bugs 概率dp 入门经典 难度:1

    Collecting Bugs Time Limit: 10000MS   Memory Limit: 64000K Total Submissions: 2745   Accepted: 1345 ...

  6. POJ 3071 Football (概率DP)

    概率dp的典型题.用dp[j][i]表示第j个队第i场赢的概率.那么这场要赢就必须前一场赢了而且这一场战胜了可能的对手.这些都好想,关键是怎么找出当前要算的队伍的所有可能的竞争对手?这个用异或来算,从 ...

  7. POJ 3071 Football:概率dp

    题目链接:http://poj.org/problem?id=3071 题意: 给定n,有2^n支队伍参加足球赛. 给你所有的p[i][j],表示队伍i打败队伍j的概率. 淘汰赛制.第一轮(1,2)两 ...

  8. POJ 2096-Collecting Bugs(概率dp入门)

    题意: 有n种bug和s种系统bug,每天发现一种bug(可能已经发现过了)所有种bug被发现的概率相同,求所有bug被发现的期望天数. 分析: dp[i][j]发现i种bug,j种系统bug期望天数 ...

  9. POJ 3071 Football 【概率DP】

    Football Football Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3734   Accepted: 1908 ...

随机推荐

  1. 浅谈React和VDom关系

    组件化 组件的封装 组件的复用 组件的封装 视图 数据 视图和数据之间的变化逻辑 import React, {Component} from 'react'; export default clas ...

  2. jquery实现表单验证简单实例

    /* 描述:基于jquery的表单验证插件. */ (function ($) { $.fn.checkForm = function (options) { var root = this; //将 ...

  3. C# Server.MapPath的使用方法

    (1)WebForm中: HttpContext.Current.Server.MapPath("~/Files/car/"); (2)Mvc中: Server.MapPath() ...

  4. Flask中那些特殊的装饰器

    模板相关的装饰器 @app.template_global() 用法: @app.template_global() # 记得加括号 def jiafa(a, b): # 这个方法每调用一次就需要传一 ...

  5. 利用HaoheDI从数据库抽取数据导入到hbase中

    下载apache-phoenix-4.14.0-HBase-1.4-bin.tar.gz 将其中的 phoenix-4.14.0-HBase-1.4-client.jar phoenix-core-4 ...

  6. day2-exercise

    # Author: 刘佳赐-Isabelle October 22,2018 """ 1.有变量name = "aleX leNb" 完成如下操作: ...

  7. Linux命令集锦

    梳理常用的Linux命令 day1--cd命令 cd命令:(注意以下的命令,cd后均有一个空格) 1.进入盘符: cd f: 2.进入当前目录命令: cd . 3.进入指定文件夹(在进入确定盘符之后, ...

  8. 北京Uber优步司机奖励政策(1月1日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  9. 成都Uber优步司机奖励政策(2月18日)

    滴快车单单2.5倍,注册地址:http://www.udache.com/ 如何注册Uber司机(全国版最新最详细注册流程)/月入2万/不用抢单:http://www.cnblogs.com/mfry ...

  10. springboot shiro没有注解解决方案

    颓废的悠然   springboot shiro开启注释 shiroconfiguration中增加 1 2 3 4 5 6 7 @Bean     public AuthorizationAttri ...