称号:背景: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;
}

版权声明:本文博客原创文章,博客,未经同意,不得转载。

最新文章

  1. 版本控制工具比较-CVS,SVN,GIT
  2. 面向移动设备的html5开发框架
  3. js简易函数性能测试器
  4. header的用法小结(转)
  5. A fatal error has been detected by the Java Runtime Environment:
  6. 学习vue 20天,我写了点东西
  7. ubuntu上lamp环境搭建
  8. maven多环境部署
  9. (八十)MapKit放置系统默认大头针和自定义大头针
  10. 解决TOC与目录导航冲突问题
  11. centos7编译安装zabbix(附带编译安装lnmp)
  12. [ /* 和 / 的区别 ] Difference between / and /* in servlet mapping url pattern
  13. Ajax 要点
  14. linux 下安装安装mysql 5.6. 5.7
  15. 《Linux内核分析》第五周学习总结 扒开系统调用的三层皮(下)
  16. STM32 CRC-32 Calculator Unit
  17. 题解 P3628 【[APIO2010]特别行动队 】
  18. 详解REST架构风格
  19. jQuery插件实例二:年华时代插件ReturnTop回到首页
  20. Struts2 S标签 数目字格式化成金额输出(保留两位小数)

热门文章

  1. Wix学习整理(1)——快速入门HelloWorld
  2. hdu4283(区间dp)
  3. hdu1292(递推dp)
  4. 自己动手写了第三阶段的处理器——教学OpenMIPS处理器蓝图
  5. Linux+Apache+Mysql+Php
  6. RequireJS和JQuery的模块化编程
  7. Python眼睛护士改进版
  8. EJBTimer 使用EJB提供的定时器
  9. python手记(48)
  10. Cannot instantiate the type List&amp;lt;Integer&amp;gt;