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 ( 1
n
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颗糖的小篮子.他每次选择一堆糖果,把最顶上的一颗拿到篮子里.如果篮子 ...
随机推荐
- React Router 4 的使用(2)
Route Rendering Props 对于给定的路由如何渲染组件,有三种选项:component.render.children.你可以查看 <Route> 的文档来获取更多的信息, ...
- 优雅的QSignleton (三) 通过属性器实现Singleton
接下来介绍,不通过继承的方式实现单例模式.大家都出去嗨了,而我却在家码代码... 代码如下: MonoSingletonProperty.cs namespace QFramework.Example ...
- spring入门(三) 使用spring mvc
1.建立project / module 新建空的project:springMvcStudy 新建module:type maven-webapp,名字mvcStudy 2.为module设置Sou ...
- JavaScript 基础(五) 函数 变量和作用域
函数定义和调用 定义函数,在JavaScript中,定义函数的方式如下: function abs(x){ if(x >=0){ return x; }else{ return -x; } } ...
- FastJson反序列化漏洞利用的三个细节 - TemplatesImpl的利用链
0. 前言 记录在FastJson反序列化RCE漏洞分析和利用时的一些细节问题. 1. TemplatesImpl的利用链 关于 parse 和 parseObject FastJson中的 pars ...
- bzoj3895: 取石子(博弈论,记忆化搜索)
3895: 取石子 Time Limit: 1 Sec Memory Limit: 512 MBSubmit: 361 Solved: 177[Submit][Status][Discuss] D ...
- Java 的标识接口作用
原文地址:标识接口 作用作者:feisong 时间:2019-01-2315:49:35 标识接口是没有任何方法和属性的接口.标识接口不对实现它的类有任何语义上的要求,它仅仅表明实现它的类属于一个特定 ...
- Ajax在表单中的应用
ajax在注册用户表单中的使用 1.验证用户名是否被使用 2.获取手机短信验证码 3.点击表单中的图片刷新,可实现刷新图片验证码 <!DOCTYPE html> <html> ...
- java简单web爬虫(网页图片)
java简单web爬虫(网页图片)效果,执行main()方法后图片就下载道C盘的res文件夹中.没有的话创建一个文件夹代码里的常量根据自己的需求修改,代码附到下面. package com.sinit ...
- Apache httpd Server 配置正向代理
背景 代理(Proxy),位于客户端与实际服务端之间,当客户端需要请求服务端内容时,先向代理发起请求,代理将请求转发到实际的服务器,再原路返回.也可以在代理服务器设置缓存,将实际服务器上不常变化的内容 ...




