UVa 11587 - Brick Game
称号:背景:brick game有N块,给你一个整数的定数S,两个人轮流木;
的木块数是集合S中存在的随意数字。取走最后木块的人获胜。无法取则对方获胜。
题干:如今让你先取,给你一个你的结果序列串T,当中第k个字符代表有k个木块时你的结果:
可能赢就是T[k] = W。一定输就是T[k] = L。
问题:请你确定一个最小的集合,使得这个序列串T成立。(集合中元素为不超过20的正整数)
分析:博弈,状态压缩+dp验证。
由于集合最多20个元素,利用20个位表示每一个元素(1~20)的选取状态。
枚举全部可能情况,然后利用dp计算每种情况下的结果序列。推断是否和输入同样就可以。
1.枚举的时候,依照集合元素的递增顺序就可以,那么第一个满足T串的集合就是所求解。
位运算计算全组合C(n,k)代码:
xx,yy,comb = (1<<k)-1;
while ( comb < (1<<n) ) {
//存储相应位的数值
xx = comb&-comb,yy = comb+xx;
comb = ((comb&~yy)/xx>>1)|yy;
}
2.模拟的时候,利用dp求解(类似01背包),假设如今状态是可能赢,那么它之前状态一定输。
所以有状态转移方程: M[i] = 'W' 存在M[i-S[j]] = ‘L’
M[i] = 'L' 不存在M[i-S[j]] = ‘L’
dp过程代码:
for ( i = 1 ; i <= L ; ++ i )
for ( j = 1 ; j <= k ; -- j )
if ( M[i-S[j]] == 'L' )
M[i] = 'W';
由于dp过程是按位的长度进行的,能够一边计算一边比較提高效率。
注意:数据中存在“全是'L'的情况,输出长度+1就可以。
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <cstdio>
#include <cmath> using namespace std; char T[128],M[128];
int S[32]; int tests( int n, int L )
{
int N = (1<<n),k,i,j,count,flag;
/*全是'L'的情况*/
int tes = 0;
for ( k = 1 ; k <= L ; ++ k )
if ( T[k] == 'W' ) {
tes = 1; break;
}
if ( !tes ) {
printf(" %d\n",n+1);
return 1;
} /*存在'W'的情况*/
/*计算顺序调整。是为了满足题目要求顺序*/
for ( k = n ; k >= 1 ; -- k ) {
int xx,yy,comb = (1<<k)-1;
while ( comb <= N ) {
/* 计算当前状态相应的集合 */
j = 0,count = 0;
do {
if ( !((1<<j)&comb) ) S[++ count] = n-j;
j ++;
}while ( j < n ); /* dp求解集合可以产生的结果串 */
flag = 1;
for ( i = 0 ; i <= L ; ++ i )
M[i] = 'L';
for ( i = 1 ; i <= L ; ++ i ) {
for ( j = count ; j >= 1 ; -- j ) {
if ( S[j] > i ) break;
if ( M[i-S[j]] == 'L' )
M[i] = 'W';
}
if ( M[i] != T[i] ) {
flag = 0;
break;
}
}
/* 满足题意的解输出 */
if ( flag ) {
for ( i = count ; i >= 1 ; -- i )
printf(" %d",S[i]);
printf("\n");
return 1;
} /* 位运算计算下一集合,依照顺序递增 */
xx = comb&-comb,yy = comb+xx;
comb = ((comb&~yy)/xx>>1)|yy;
}
}
return 0;
} int main()
{
int n;
while ( ~scanf("%d",&n) )
for ( int t = 1 ; t <= n ; ++ t ) {
scanf("%s",&T[1]);
int L = strlen(&T[1]); printf("Case %d:",t);
tests( min(20,L), L );
}
return 0;
}
版权声明:本文博客原创文章,博客,未经同意,不得转载。
UVa 11587 - Brick Game的更多相关文章
- UVa 900 - Brick Wall Patterns
题目大意:用1*2的砖头建n*2的墙,问有多少种不同的砖头排列方式?与斐波那契序列相似. #include <cstdio> #define MAXN 60 #define N 50 un ...
- uva 1354 Mobile Computing ——yhx
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5
- UVA 10564 Paths through the Hourglass[DP 打印]
UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...
- UVA 11404 Palindromic Subsequence[DP LCS 打印]
UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...
- UVA&&POJ离散概率与数学期望入门练习[4]
POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...
- UVA计数方法练习[3]
UVA - 11538 Chess Queen 题意:n*m放置两个互相攻击的后的方案数 分开讨论行 列 两条对角线 一个求和式 可以化简后计算 // // main.cpp // uva11538 ...
- UVA数学入门训练Round1[6]
UVA - 11388 GCD LCM 题意:输入g和l,找到a和b,gcd(a,b)=g,lacm(a,b)=l,a<b且a最小 g不能整除l时无解,否则一定g,l最小 #include &l ...
- UVA - 1625 Color Length[序列DP 代价计算技巧]
UVA - 1625 Color Length 白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束 和模拟赛那道环形DP很想,计算这 ...
- UVA - 10375 Choose and divide[唯一分解定理]
UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS Memory Limit: 65536K Total Subm ...
随机推荐
- poj3984(经典dfs)
题目链接:http://poj.org/problem?id=3984 分析:直接深搜从起点到终点,如何取最短路线,其实只要优先向下或向右走即可. #include <cstdio> #i ...
- hdu2606(递推)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2606 题意: 用1*1,2*2,3*3,4*4的正方形填充4*n的矩形, 问有多少种不同填法. 分析 ...
- 【转】Vim学习资料
初学资料:1:一个介绍VIM操作的游戏,十分适合初学者.只是:不要怕英文.vim-adventures.com2:http://blog.csdn.net/niushuai666/article/de ...
- JavaScript中的对象(一)
Email:longsu2010 at yeah dot net 最近我和朋友谈起JavaScript中对象的问题.朋友以写JavaScript为生,而且生活的很好,然而我发现他并不真正懂这们语言的某 ...
- Linux进程间通信(九)---综合实验之有名管道通信实验
实验目的 通过编写有名管道多路通信实验,进一步掌握管道的创建.读写等操作,同时复习使用select()函数实现管道的通信. 实验内容 这里采用管道函数创建有名管道(不是在控制台下输入命令mknod), ...
- Knockout应用开发指南 第九章:高级应用举例
原文:Knockout应用开发指南 第九章:高级应用举例 1 Contacts editor 这个例子和微软为演示jQuery Data Linking Proposal例子提供的例子一样的提供的 ...
- U7Linux文件与目录管理
1. .:代表当前层目录. ..:代表上一层目录. -:代表前一个工作目录. ~:代表目前用户所在的主文件夹. ~account:代表account这个用户的主文件夹. 2.pwd:显示当前目录. p ...
- Sql SUBSTR函数
SUBSTR( ) 从一个字符表达式或备注字段中返回一个字符串.该字符串起始于字符表达式或备注字段的指定位置,到指定数目字符结束. 例如: SUBSTR(“A1”, 1 1]) 结果:A
- oracle 11g impdp时 报ORA-12899(转)
源库ZHS16BGK,汉字在数据库存放的时候占用两个字节 目标库UTF8,汉字在数据库里存放的时候占用三个字节 由于字符集不同,导致现在数据库impdp的时候有些表的字段长度不够,出现ORA-1289 ...
- 通过 HTTP 头进行 SQL 注入(转)
英文原文:DatabaseTube,翻译:开源中国 在漏洞评估和渗透测试中,确定目标应用程序的输入向量是第一步.这篇文章解释了别人是如何通过HTTP头部对你的数据库进行SQL注入攻击的,以及讨论下选择 ...