时间限制: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
****************************************************************/

最新文章

  1. poj 1724:ROADS(DFS + 剪枝)
  2. java list 交集 并集 差集 去重复并集
  3. Android - 动态调整ListView高度
  4. github配置
  5. js对数组的操作函数
  6. 使用 Acegi 保护 Java 应用程序
  7. C++中new的用法
  8. 黑马程序员_Java面向对象2_继承
  9. BUAA 更大公约数
  10. Is it possible to implement a Firebug-like “inspect element” DOM element highlighter with client-side JavaScript?
  11. SAP 金税接口介绍
  12. IM 融云 之 开发基础概念
  13. JAVA之旅(十七)——StringBuffer的概述,存储,删除,获取,修改,反转,将缓存区的数据存储到数组中,StringBuilder
  14. FastDFS 与 Nginx 实现分布式图片服务器
  15. Building Microservices with Spring Boot and Apache Thrift. Part 2. Swifty services
  16. 弹指之间 -- Waltz
  17. Matlab矩阵基本操作(定义,运算)
  18. python的post请求抓取数据
  19. WAL日志文件名称格式详解
  20. 算法初步——two pointers

热门文章

  1. 2017年开发者生态报告:Python最多人想尝试的编程语言(转载)
  2. [转载]Redis后台启动
  3. 安装openstack 时 遇见的一些问题及解决方法!
  4. python 奇技淫巧
  5. springboot jpa | mybaits
  6. 1、硬件IO口配置;
  7. git merge 和 git rebase 小结(转)
  8. java清除所有微博短链接 Java问题通用解决代码
  9. android tooggle button
  10. ASP.NET中的配置文件