时间限制: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. ieda常用快捷键

    Ctrl+Shift + Enter,语句完成“!”,否定完成,输入表达式时按 “!”键Ctrl+E,最近的文件Ctrl+Shift+E,最近更改的文件Shift+Click,可以关闭文件Ctrl+[ ...

  2. IntelliJ IDEA 取消控制台行数限制

    在idea7之后的版本中取消了 控制台行数设置 选项,只能通过更改配置文件进行更改 在%安装目录%/bin中找到idea.properties文件,更改idea.cycle.buffer.size项值 ...

  3. org.apache.hadoop.ipc.RemoteException: User: root is not allowed to impersonate root

    修改 core-site.xml文件 vim /usr/local/hadoop/etc/hadoop/core-site.xml 增加: <property> <name>h ...

  4. javascript 回车实现 tab 切换功能完美解决

    最经有一个项目是给化工厂做的在使用的过程中需要输入大量的数据,使用的都是小键盘区,在以前都是通过excel录入数据的现在, 在网页上需要实现excel 那样的回车换行的功能在网上找了有关这方面的问题但 ...

  5. 用Jmeter对数据库执行压力测试

    转载:http://www.cnblogs.com/chengtch/p/6198900.html 在我看来压力测试的压测对象可以分为UI,接口及数据库三个部分吧,对界面及接口进行压测还算熟悉, 定位 ...

  6. Shell 同时读取多个文件

    现有两个文件 1.txt  2.txt,内容分别如下: [root@SHO-XXW-- readmulti]# .txt [root@SHO-XXW-- readmulti]# .txt a b c ...

  7. #include <>与#include""区别

    <>先去系统目录中找头文件,如果没有在到当前目录下找.所以像标准的头文件 stdio.h.stdlib.h等用这个方法. 而""首先在当前目录下寻找,如果找不到,再到系 ...

  8. java编程思想读书笔记 第十二章 通过异常处理错误(下)

    1.异常的限制 当覆盖方法的时候,仅仅能抛出在基类方法的异常说明里列出的那些异常. 这意味着,当基类使用的代码应用到其派生类对象的时候,一样能够工资,异常也不例外. 以下的样例是在编译时施加在异常上面 ...

  9. ubuntu安装firefox的flash插件

    1.下载插件 https://get.adobe.com/cn/flashplayer/ 下载tar.gz文件 2.解压缩 切换到下载目录,如果是默认下载的话,用 cd ~/下载/解压缩下载的文件 t ...

  10. KingdeeK3-修改单据邮件发送的自定义字段

    只需要执行类似下面语句即可: update ICTemplateentry set FVisForBillType = 63,flookupcls=6 where fid ='P01' and fhe ...