UVA 11884 A Shooting Game(记忆化搜索)
A and B are playing a shooting game on a battlefield consisting of square-shaped unit blocks. The blocks are occupying some consecutive columns, and the perimeter of the figure equals the perimeter of its minimal bounding box. The figure (a) below is a valid battlefield, but (b) and (c) are not, because in (b), there is an empty column; in (c), the perimeter of figure is 14, but the perimeter of the bounding box (drawn with dashed lines) is 12. With the help of gravity, each block is either located on another block, or sitting on the ground. To make the battlefield look more exciting, it must not be a perfect rectangle (i.e. it is not allowed that every column has the same height)

Here is the rule of the game:
- A and B shoot by turn. A starts first.
- Before shooting, the player first select one row with at least one block, and one of the two directions "left" and "right", then shoot at this row along that direction. The power of the shoot is one of 1, 2 or 3, each with probability of 1/3. The power of shoot is the number of blocks (not necessarily consecutive) that can be destroyed in this shoot. If the total number of blocks on this row is less than the power of shoot, then all the blocks on this row is destroyed. For example, if the player chooses to shoot the 3rd row from the bottom, with direction "right", power 2, and there are 4 blocks on this row, then the left-most two blocks are destroyed.
- After each shoot, blocks in the air fall down vertically. The next player cannot shoot before all the blocks stop falling.
- Realize that the intermediate battlefields do not have to follow the constraints for starting battlefields. For example, it could happens some situations looking as figures (b) or (c), and then, if the power is p, the leftmost/rightmost p blocks of columns which contain a block in this row are destroyed (skipping empty positions).
- He who destroys the last block wins.
Assume the starting battlefield is . According to rule 1, A shoots first. The table below shows three (not all) possible outcomes of the first shot:
Row(from bottom) | Direction | Power | Befrore Falling | Stable |
2 | Left | 1 | ![]() |
(Same as left) |
1 | Left | 2 | ![]() |
![]() |
1 | Right | 3 | ![]() |
![]() |
Assume Alice and Bob are both very clever (always follows the strategy that maximizes the probability he/she wins), what is the probability that Alice wins?
Input
There will be at most 25 test cases, each with two lines. The first line is a single integer n ( 1n
6), the number of columns. The second line contains n integers h1, h2, ..., hn ( 1
hi
6), the heights of the columns from left to right. The battlefield is guaranteed to satisfy the restrictions in the problem (perimeter of figure equals that of the minimal bounding box, and is not a perfect rectangle). Input is terminated by n = 0.
Output
For each test case, print a single line, the probability that A wins, to six decimal points.
题目大意:题目好长>_<。大致是说有一个游戏,有n列,每列最多6个方块,这些方块是垂直放的如果下面没有东西了就会垂直掉下来(初始方块的状态有限制条件不过这题没用)。现在有两个人玩游戏,他们各有一支枪,每发子弹的攻击力为1、2或3,概率均为1/3。可以选择从左攻击或从右攻击,可以自己选择一行,发射子弹之后最多打掉子弹攻击力个方块(如果子弹攻击力比方块多,那么就只有浪费掉了),然后悬浮的方块会往下掉。现在这两个人都足够聪明,每次都会选择胜率最高的来开枪,问先手的胜率。
思路:容易看出状态数最多有7^6=117649种,记忆化搜索可以解决(我总觉得这是暴力求破)。分别计算从左边六行发射子弹的胜率,再计算右边六行发射子弹的胜率,取最大的一个(这玩游戏的人真是神智商,你以为个个都是冯洛伊曼吗……)。用dp[x1][x2][x3][x4][x5][x6]来记录一个人面临第一列x1个,第二列x2个……的状态的胜率即可。注意处理细节还是比较容易AC的。
代码(32MS):
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <cmath>
using namespace std;
typedef long long LL;
#define FOR(i, s, t) for(int i = s; i <= t; ++i) const int MAXS = ;
const int MAXN = ;
const double EPS = 1e-; double a[][][][][][]; double solve(int p1, int p2, int p3, int p4, int p5, int p6) {
if(a[p1][p2][p3][p4][p5][p6] > EPS) return a[p1][p2][p3][p4][p5][p6];
if(p1 + p2 + p3 + p4 + p5 + p6 == ) return ;
int v1, v2, v3, v4, v5, v6;
double ret = ;
for(int i = ; i <= ; ++i) {
double tmp = ;
for(int j = ; j <= ; ++j) {
v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6;
int k = j;
if(v1 >= i && k) --v1, --k;
if(v2 >= i && k) --v2, --k;
if(v3 >= i && k) --v3, --k;
if(v4 >= i && k) --v4, --k;
if(v5 >= i && k) --v5, --k;
if(v6 >= i && k) --v6, --k;
if(k == j) continue;
tmp += ./ * ( - solve(v1, v2, v3, v4, v5, v6));
}
if(tmp > ret) ret = tmp;
tmp = ;
for(int j = ; j <= ; ++j) {
v1 = p1, v2 = p2, v3 = p3, v4 = p4, v5 = p5, v6 = p6;
int k = j;
if(v6 >= i && k) --v6, --k;
if(v5 >= i && k) --v5, --k;
if(v4 >= i && k) --v4, --k;
if(v3 >= i && k) --v3, --k;
if(v2 >= i && k) --v2, --k;
if(v1 >= i && k) --v1, --k;
if(k == j) continue;
tmp += ./ * ( - solve(v1, v2, v3, v4, v5, v6));
}
if(tmp > ret) ret = tmp;
}
return a[p1][p2][p3][p4][p5][p6] = ret;
} int x[], n; int main() {
//FOR(i1, 0, 6) FOR(i2, 0, 6) FOR(i3, 0, 6) FOR(i4, 0, 6) FOR(i5, 0, 6) FOR(i6, 0, 6)
//if(a[i1][i2][i3][i4][i5][i6] < EPS) solve(i1, i2, i3, i4, i5, i6);
while(scanf("%d", &n) != EOF && n) {
memset(x, , sizeof(x));
for(int i = ; i <= n; ++i) scanf("%d", &x[i]);
printf("%.6f\n", solve(x[], x[], x[], x[], x[], x[]));
}
}
UVA 11884 A Shooting Game(记忆化搜索)的更多相关文章
- UVa 10599【lis dp,记忆化搜索】
UVa 10599 题意: 给出r*c的网格,其中有些格子里面有垃圾,机器人从左上角移动到右下角,只能向右或向下移动.问机器人能清扫最多多少个含有垃圾的格子,有多少中方案,输出其中一种方案的格子编号. ...
- UVa 1629 切蛋糕(记忆化搜索)
https://vjudge.net/problem/UVA-1629 题意: 有一个n行m列的网格蛋糕上有一些樱桃.每次可以用一刀沿着网格线把蛋糕切成两块,并且只能直切不能拐弯.要求最后每一块蛋糕上 ...
- UVa 10118 Free Candies (记忆化搜索+哈希)
题意:有4堆糖果,每堆有n(最多40)个,有一个篮子,最多装5个糖果,我们每次只能从某一堆糖果里拿出一个糖果,如果篮子里有两个相同的糖果, 那么就可以把这两个(一对)糖果放进自己的口袋里,问最多能拿走 ...
- uva 10911 - Forming Quiz Teams(记忆化搜索)
题目链接:10911 - Forming Quiz Teams 题目大意:给出2 * n个选手的坐标, 要求将所有的选手分成n组, 每组两个人, 所有组的两个人之间的距离之和要最小, 输出最小值. 解 ...
- UVa 674 Coin Change【记忆化搜索】
题意:给出1,5,10,25,50五种硬币,再给出n,问有多少种不同的方案能够凑齐n 自己写的时候写出来方案数老是更少(用的一维的) 后来搜题解发现,要用二维的来写 http://blog.csdn. ...
- UVa 1252 (状压DP + 记忆化搜索) Twenty Questions
题意: 有n个长为m的各不相同的二进制数(允许存在前导0),别人已经事先想好n个数中的一个数W,你要猜出这个数. 每次只可以询问该数的第K为是否为1. 问采用最优询问策略,则最少需要询问多少次能保证猜 ...
- UVa 10817 (状压DP + 记忆化搜索) Headmaster's Headache
题意: 一共有s(s ≤ 8)门课程,有m个在职教师,n个求职教师. 每个教师有各自的工资要求,还有他能教授的课程,可以是一门或者多门. 要求在职教师不能辞退,问如何录用应聘者,才能使得每门课只少有两 ...
- UVa 1252 - Twenty Questions(记忆化搜索,状态压缩dp)
本文出自 http://blog.csdn.net/shuangde800 题目链接:点击打开链接 题目大意 有n个长度为m的二进制串,每个都是不同的. 为了把所有字符串区分开,你可以询问,每次可 ...
- uva 10123 - No Tipping dp 记忆化搜索
这题的题意是 在双脚天平上有N块东西,依次从上面取走一些,最后使得这个天平保持平衡! 解题: 逆着来依次放入,如果可行那就可以,记得得有木板自身的重量. /********************** ...
- UVa 10118 免费糖果(记忆化搜索+哈希)
https://vjudge.net/problem/UVA-10118 题意: 桌上有4堆糖果,每堆有N颗.佳佳有一个最多可以装5颗糖的小篮子.他每次选择一堆糖果,把最顶上的一颗拿到篮子里.如果篮子 ...
随机推荐
- papers-06-02
午睡被同事吵醒,只好干活.看到微信公众号有一篇文章说老朋友呢,点进去发现原来相关的工作好多,而且好新好细致. 微信的文章可以见这里: 探究最陌生的老朋友Softmax 里面的几篇文章可以看看. Lar ...
- Python学习之路——文件操作
文件操作分三步:打开文件,读写文件,关闭文件.读取操作时没有给read函数加括号,会出现下面这样的车祸 >>> data = open('/home/supersun/Documen ...
- Java基础——XML复习
XML SGML : 标准通用置标语言 Standard Generailzed Markup Language XML ...
- iOS之Xcode自动管理证书、打包adhoc和testFlight测试安装
引言:Xcode8 之后引用Automatic manage signing .对于开发者而言,在证书上栽的坑肯定不少. 准备:1.开发者账号是必须的吧. 2. Xcode设置account (不给 ...
- For macOS.百度网盘 破解SVIP、下载速度限制~
For macOS.百度网盘 破解SVIP.下载速度限制~ 是插件的 https://github.com/CodeTips/BaiduNetdiskPlugin-macOS 2019-01-03 让 ...
- yum仓库客户端搭建和NTP时间同步客户端配置
一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...
- 如何本地搭建centos7虚拟主机?
1 前期准备: 下载虚拟机和CentOS安装源 VMware-workstation-full-10.0.3-1895310 CentOS-7.0-1406-x86_64-DVD.iso 以下是过 ...
- Linux Shell常用命令(长期更新)
#判断某个字段是否匹配指定值 awk -F"," '{if($4=="value"){print $1} else {print $0}}' file.txt ...
- Java : java基础(3) IO流
流按操作类型分为两种,字节流,字符流,按流向分为输入流,输出流,输入流的抽象父类InputStream,输出流抽象父类OutputStream,字符流的抽象父类是Reader和Writer 一般用字节 ...
- 关于使用array_rand随机取出数组的值
代码如下 <?php echo "<meta charset='utf-8'/>";//选择解码方式,防止乱码现象 $a = array("abc&qu ...