时间限制:3 秒

内存限制:32 兆

特殊判题:否

提交:213

解决:66

题目描述:
角斗士是古罗马奴隶社会的一种特殊身份的奴隶,他们的职责是在角斗场上进行殊死搏斗,为了人们提供野蛮的娱乐。他们的结局或是战死,或者由于表现突出赢得胜利而获得释放。
现在在角斗场里有N个待战的角斗士(1 <=N<=18),每天都将举行一场比赛,为了保持比赛的刺激性,每场比赛前才会在所有当前活着的角斗士之中随机选择两名进行上场拼杀。每场比赛的结束条件即为其中一名被杀死。当进行了N场比赛之后,最后存活的角斗士将被释放。而你将被赋予一个任务,计算出每名角斗士最终存活的概率。我们将提供角斗士之间对战获胜的概率。
输入:
测试数据包括多个,每个测试数据包含两部分
首先第一行将输入一个整数N,其中1 <= N <= 18,代表角斗士的个数。
接下来将是一个N * N大小的概率矩阵P,代表角斗士之间战斗的获胜概率,例如P[i][j]就代表角斗士i战胜j的概率;同样P[j][i]则代表角斗士j战胜i的概率。我们保证P[i][j] + P[j][i] = 1。同时我们规定当i等于j时,P[i][j] 为 0。
输出:
对于每个测试案例,输出一行,包含N个小数,中间用空格隔开,分别代表第0、1、…、N个角斗士存活下来的概率,每个小数精确到小数点后3位。
样例输入:
2
0 0.5
0.5 0
3
0 1 1
0 0 0.5
0 0.5 0
样例输出:
0.500 0.500
1.000 0.000 0.000

思路:

参考别人的思路写的。

状态压缩DP。

初看规模,n只有18,马上想到是dfs搜索或者是状态压缩dp。

令数组dp[x]表示x在二进制上为1那些人活着的概率,比如现在只有3个人,

那么dp[5]表示第一个人和第三个人活着的概率。

由于比赛是随即选择两个人,那么每场比赛的概率为1 / C(活着的人的个数,2)。

最终的概率应该是叠加上去。

那么状态转移方程为pos[i ^ (1 << j)] += pos[i] * win[j][k] / sum。

代码:

#include <stdio.h>

#define N 18
#define M (1<<N) int survive(int k, int n)
{
int i, count;
count = 0;
for (i=0; i<n; i++)
{
count += (k & 1);
k >>= 1;
}
return count;
} int main()
{
int i, j, k, n;
double P[N][N], S[M];
while(scanf("%d", &n) != EOF)
{
for (i=0; i<n; i++)
{
for (j=0; j<n; j++)
{
scanf("%lf", &P[i][j]);
}
} for (k = (1<<n) - 1; k>0; k--)
S[k] = 0;
S[(1<<n) - 1] = 1;
for (k = (1<<n) - 1; k>0; k--)
{
int count;
count = survive(k, n);
//printf("%d, %d\n", k, count);
if (count == 1)
continue;
int num = count*(count-1)/2;
for (j=0; j<n; j++)
{
int bitJ = 1<<j;
if ((k & bitJ) == 0)
continue;
int nk = (k ^ bitJ);
//printf("k=%d, count=%d, nk=%d\n", k, count, nk);
double tmpS = 0;
for (i=0; i<n; i++)
{
int bitM = 1<<i;
if ((nk & bitM) == 0)
continue;
//printf("i=%d, j=%d\n", i, j);
tmpS += P[i][j];
}
tmpS *= S[k];
tmpS /= num;
S[nk] += tmpS;
//printf("S[%d]=%.3lf\n", nk, S[nk]);
}
} //for (k = (1<<n) - 1; k>0; k--)
// printf("%.3lf\n", S[k]);
for (i=0; i<n-1; i++)
printf("%.3lf ", S[1<<i]);
printf("%.3lf\n", S[1<<i]);
}
return 0;
}
/**************************************************************
Problem: 1338
User: liangrx06
Language: C
Result: Accepted
Time:980 ms
Memory:2892 kb
****************************************************************/

九度OJ 1338:角斗士 (递归、DP)的更多相关文章

  1. 九度OJ 1552座位问题(dp)

    刚开始写的一维数组,但是由于后面的数字较大,要对它取模,所以用一维数组进行减法运算,结果就不对了.所以还是得用二维数组,用dp[n][0]来表示第n位为男生总的方法个数,dp[n][1]表示第n位为女 ...

  2. 【九度OJ】题目1205:N阶楼梯上楼问题 解题报告

    [九度OJ]题目1205:N阶楼梯上楼问题 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1205 题目描述: N阶楼梯上楼问题:一次 ...

  3. 九度OJ 1500 出操队形 -- 动态规划(最长上升子序列)

    题目地址:http://ac.jobdu.com/problem.php?pid=1500 题目描述: 在读高中的时候,每天早上学校都要组织全校的师生进行跑步来锻炼身体,每当出操令吹响时,大家就开始往 ...

  4. 九度OJ 1531 货币面值(网易游戏2013年校园招聘笔试题) -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1531 题目描述: 小虎是游戏中的一个国王,在他管理的国家中发行了很多不同面额的纸币,用这些纸币进行任意的组合可以在 ...

  5. hdu 1284 关于钱币兑换的一系列问题 九度oj 题目1408:吃豆机器人

    钱币兑换问题 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Sub ...

  6. 【九度OJ】题目1078:二叉树遍历 解题报告

    [九度OJ]题目1078:二叉树遍历 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1078 题目描述: 二叉树的前序.中序.后序遍历 ...

  7. 【九度OJ】题目1475:IP数据包解析 解题报告

    [九度OJ]题目1475:IP数据包解析 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1475 题目描述: 我们都学习过计算机网络, ...

  8. 【九度OJ】题目1073:杨辉三角形 解题报告

    [九度OJ]题目1073:杨辉三角形 解题报告 标签(空格分隔): 九度OJ http://ac.jobdu.com/problem.php?pid=1073 题目描述: 输入n值,使用递归函数,求杨 ...

  9. 九度oj 题目1087:约数的个数

    题目链接:http://ac.jobdu.com/problem.php?pid=1087 题目描述: 输入n个整数,依次输出每个数的约数的个数 输入: 输入的第一行为N,即数组的个数(N<=1 ...

随机推荐

  1. python字典里的update函数

    >>> print d {'age': 34, 'name': 'jeapedu'} >>> d1={"age":38} >>> ...

  2. Linux alias理解及设置

    1.alias简介 Linux alias 是命令的一种别称,输入 alias 可以看到像下面这样的结果: alias l.='ls -d .* --color=auto' alias ll='ls ...

  3. Android之TextView的Span样式源代码剖析

    Android中的TextView是个显示文字的的UI类.在现实中的需求中,文字有各式各样的样式,TextView本身没有属性去设置实现.我们能够通过Android提供的 SpannableStrin ...

  4. How to use Variables in different component

    1. In Script Task component Set Value: Dts.Variables["ErrorMsg"].Value = string.Format(&qu ...

  5. 基于Android Classic Bluetooth的蓝牙聊天软件

    代码地址如下:http://www.demodashi.com/demo/12133.html BluetoothChat 基于Android Classic Bluetooth的蓝牙聊天软件,目前仅 ...

  6. hdu 2871 Memory Control(线段树)

    题目链接:hdu 2871 Memory Control 题目大意:模拟一个内存分配机制. Reset:重置,释放全部空间 New x:申请内存为x的空间,输出左地址 Free x:释放地址x所在的内 ...

  7. java 根据生日计算年龄 Java问题通用解决代码

    根据生日计算年龄可以通过Calendar实现.最简单可以考虑get(Calendar.DAY_OF_YEAR)来简单修正年龄,但是遇到生日在闰年的2月29之后,或者今年是闰年的2月29之后可能出现计算 ...

  8. C# 指南之装箱与拆箱

    基础 1.值类型 1.1 在栈上分配内存,在声明时初始化才能使用,不能为null. 1.2 值类型超出作用范围系统自动释放内存. 1.3 主要由两类组成:结构,枚举 结构分为以下几类 1.整形(Sby ...

  9. WordPress系列之钩子hook的作用及基本用法

    WordPress 的插件机制实际上只的就是这个 Hook 了,它中文被翻译成钩子,允许你参与 WordPress 核心的运行,是一个非常棒的东西,下面我们来详细了解一下它.钩子分类 钩子分为两种,一 ...

  10. 转 RabbitMQ

    转自:https://blog.thankbabe.com/2017/08/03/rabbitmq-demo/?from=cnblogs 介绍 RabbitMQ是一个由erlang开发的基于AMQP( ...