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颗糖的小篮子.他每次选择一堆糖果,把最顶上的一颗拿到篮子里.如果篮子 ...
随机推荐
- JWT如何在Spring Cloud微服务系统中在服务相互调时传递
转载请标明出处: http://blog.csdn.net/forezp/article/details/78676036 本文出自方志朋的博客 在微服务系统中,为了保证微服务系统的安全,常常使用jw ...
- Java实现双向冒泡排序
public class BubbleSort_Two { public static void bubbleSort_Two(int[] list){ //j在最外层定义 boolean needN ...
- 基于 UIImagePickerController 的拓展封装 - iOS
基于 UIImagePickerController 的拓展,分别支持调用相机.相册的功能,其中相机可以设置默认调用前后摄像头; 简单对此进行了封装和实现,其中还有很多点可以继续挖掘和优化,该版本具体 ...
- iOS 让视图UIView单独显示某一侧的边框线
iOS 让视图UIView 单独显示某一侧的边框线 有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...
- ABAP术语-Purchase Order
Purchase Order 原文:http://www.cnblogs.com/qiangsheng/archive/2008/03/07/1094717.html Request or instr ...
- 增删改查 报异常org.springframework.dao.InvalidDataAccessApiUsageException: Write operations are not allowed in read-only mode (FlushMode.MANUAL): Turn your Session into FlushMode.COMMIT/AUTO or remove 'readO
可能是Spring配置文件 事务通知里面的方法 与实际方法不匹配 <tx:advice id="advice" transaction-manager="tran ...
- jquery点击按钮复制内容
做移动端的项目遇到一个需求要点击按钮复制dom里的内容,看了很多资料显示必须textarea或者input里的内容才能简单复制,还有就是用插件的了,最终都因为遇到各种问题放弃,最终选择了最简单的点击复 ...
- Asp.NET Core 在IIS部署 An assembly specified in the application dependencies manifest was not found
今天在发布应用的时候,出来了一个报错:An assembly specified in the application dependencies manifest was not found 情况如下 ...
- ECSHOP和SHOPEX快递单号查询EMS插件V8.6专版
发布ECSHOP说明: ECSHOP快递物流单号查询插件特色 本ECSHOP快递物流单号跟踪插件提供国内外近2000家快递物流订单单号查询服务例如申通快递.顺丰快递.圆通快递.EMS快递.汇通快递.宅 ...
- itchat和matplotlib的结合使用爬取微信信息
前几天无意中看到了一片文章,<一件有趣的事:我用 Python 爬了爬自己的微信朋友>,这篇文章写的是使用python中的itchat爬取微信中朋友的信息,其中信息包括,昵称.性别.地理位 ...




