博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
H - A Shooting Game
阅读量:5115 次
发布时间:2019-06-13

本文共 2745 字,大约阅读时间需要 9 分钟。

题目:

题目大意:题目好长>_<。大致是说有一个游戏,有n列,每列最多6个方块,这些方块是垂直放的如果下面没有东西了就会垂 直掉下来(初始方块的状态有限制条件不过这题没用)。现在有两个人玩游戏,他们各有一支枪,每发子弹的攻击力为1、2或3,概率均为1/3。可以选择从左 攻击或从右攻击,可以自己选择一行,发射子弹之后最多打掉子弹攻击力个方块(如果子弹攻击力比方块多,那么就只有浪费掉了),然后悬浮的方块会往下掉。现 在这两个人都足够聪明,每次都会选择胜率最高的来开枪,问先手的胜率。

思路:容易看出状态数最多有7^6=117649种,记忆化搜索可以解决(我总觉得这是暴力求破)。分别计算从左边六行发射子弹的胜 率,再计算右边六行发射子弹的胜率,取最大的一个(这玩游戏的人真是神智商,你以为个个都是冯洛伊曼吗……)。用dp[x1][x2][x3][x4] [x5][x6]来记录一个人面临第一列x1个,第二列x2个……的状态的胜率即可。注意处理细节还是比较容易AC的。

1 #include 
2 #include
3 #include
4 #include
5 #include
6 using namespace std; 7 typedef long long LL; 8 #define FOR(i, s, t) for(int i = s; i <= t; ++i) 9 10 const int MAXS = 50010;11 const int MAXN = 8;12 const double EPS = 1e-8;13 14 double a[7][7][7][7][7][7];15 16 double solve(int p1, int p2, int p3, int p4, int p5, int p6) {17 if(a[p1][p2][p3][p4][p5][p6] > EPS) return a[p1][p2][p3][p4][p5][p6];18 if(p1 + p2 + p3 + p4 + p5 + p6 == 0) return 0;19 int v1, v2, v3, v4, v5, v6;20 double ret = 0;21 for(int i = 1; i <= 6; ++i) {22 double tmp = 0;23 for(int j = 1; j <= 3; ++j) {24 v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6;25 int k = j;26 if(v1 >= i && k) --v1, --k;27 if(v2 >= i && k) --v2, --k;28 if(v3 >= i && k) --v3, --k;29 if(v4 >= i && k) --v4, --k;30 if(v5 >= i && k) --v5, --k;31 if(v6 >= i && k) --v6, --k;32 if(k == j) continue;33 tmp += 1./3 * (1 - solve(v1, v2, v3, v4, v5, v6));34 }35 if(tmp > ret) ret = tmp;36 tmp = 0;37 for(int j = 1; j <= 3; ++j) {38 v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6;39 int k = j;40 if(v6 >= i && k) --v6, --k;41 if(v5 >= i && k) --v5, --k;42 if(v4 >= i && k) --v4, --k;43 if(v3 >= i && k) --v3, --k;44 if(v2 >= i && k) --v2, --k;45 if(v1 >= i && k) --v1, --k;46 if(k == j) continue;47 tmp += 1./3 * (1 - solve(v1, v2, v3, v4, v5, v6));48 }49 if(tmp > ret) ret = tmp;50 }51 return a[p1][p2][p3][p4][p5][p6] = ret;52 }53 54 int x[7], n;55 56 int main() {57 //FOR(i1, 0, 6) FOR(i2, 0, 6) FOR(i3, 0, 6) FOR(i4, 0, 6) FOR(i5, 0, 6) FOR(i6, 0, 6)58 //if(a[i1][i2][i3][i4][i5][i6] < EPS) solve(i1, i2, i3, i4, i5, i6);59 while(scanf("%d", &n) != EOF && n) {60 memset(x, 0, sizeof(x));61 for(int i = 1; i <= n; ++i) scanf("%d", &x[i]);62 printf("%.6f\n", solve(x[1], x[2], x[3], x[4], x[5], x[6]));63 }64 }

 

转载于:https://www.cnblogs.com/scnuacm/p/3280332.html

你可能感兴趣的文章
编写并提取简易 ShellCode
查看>>
C++反汇编: 基础知识(7)
查看>>
Linux 系统下提取 ShellCode
查看>>
VS2013+WDK8.1 驱动开发环境配置
查看>>
远程缓冲区溢出分析
查看>>
Windows 32位-调试与反调试
查看>>
WinDBG 配置内核双机调试
查看>>
WinRAR 去广告的姿势
查看>>
驱动还原:恢复SSDT内核钩子(2)
查看>>
驱动保护:挂接SSDT内核钩子(1)
查看>>
驱动通信:驱动与应用的通信(3)
查看>>
RPC和HTTP
查看>>
shell基本语法
查看>>
测试环境搭建
查看>>
java之高并发锁
查看>>
接口自动化过程中遇到的问题?
查看>>
数据库之索引
查看>>
每天有80亿的文件需要存储,你会怎么设计存储和检索?
查看>>
接口自动化的闭环?
查看>>
python小记(5)装饰器/迭代器
查看>>