状态压缩dp解博弈问题(记忆化搜索)。比赛的时候最后才开始做这道题,而且当时不知道为什么一直犯一些很2B的问题,导致没能ac,晚上看了看原先的代码,改了一下就MLE了。。。我原先是开的dp[1 << 24] 的记忆化数组,果断超内存了,然后仔细看了一下题目,发现题目中的n >= 12,也就是说用到的状态不超过2^12个,于是把满足情况的状态hash到2^12以内的数组就可以了。

思路:

因为只有24条边,所以可以考虑把边压缩,于是就转化成了普通的状态了,然后用dp数组表示该状态下先手能得到的最大分值。也就是处于该状态时,先手放一条边以后得使得后手得分最少,因为总分是一定的,这样的话先手就可以得到最优解了。然后就记忆化搜索一下就可以了。我hash用的是数组存储,二分查找下标的方法,时间效率不是很高。。。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<fstream>
#include<sstream>
#include<bitset>
#include<vector>
#include<string>
#include<cstdio>
#include<cmath>
#include<stack>
#include<queue>
#include<stack>
#include<map>
#include<set>
#define FF(i, a, b) for(int i=a; i<b; i++)
#define FD(i, a, b) for(int i=a; i>=b; i--)
#define REP(i, n) for(int i=0; i<n; i++)
#define CLR(a, b) memset(a, b, sizeof(a))
#define debug puts("**debug**")
#define LL long long
#define PB push_back
using namespace std; const int N= 1 << 13;
const int INF = 1e9; int dp[N], n, mp[N];
int gogo[22][22], num; void get_gogo()
{
int i , j = 0;
for(i = 1; i < 16; i ++)
{
if(i % 4 == 0) continue;
gogo[i][i + 1] = j;
j ++;
}
for(i = 1; i <= 12; i ++)
{
gogo[i][i + 4] = j;
j ++;
}
} bool ok(int k, int i)
{
return (k & (1 << i)) && (k & (1 << (i + 3))) && (k & (1 << ((i / 3) + i + 12))) && (k & (1 << ((i / 3) + i + 13)));
} int get_f(int k)
{
int i, j, ret = 0;
for(i = 0; i < 9; i ++)
{
if((k & (1 << i)) && ok(k, i))
ret ++;
}
return 9 - ret;
} int B_ser(int k)
{
int l = 0, r = num - 1, m;
while(l <= r)
{
m = (l + r) >> 1;
if(mp[m] == k) return m;
else if(mp[m] > k) r = m -1;
else l = m + 1;
}
} int dfs(int mk)
{
int k = mp[mk];
if(dp[mk] != -1) return dp[mk];
int ret = INF, i;
for(i = 0; i < 24; i ++)
{
if(((1 << i) & k) == 0)
{
ret = min(ret, dfs(B_ser(k | (1 << i))));
}
}
if(ret == INF)
{
return dp[mk] = get_f(k);
}
return dp[mk] = get_f(k) - ret;
} int main()
{
//freopen("input.txt", "r", stdin);
int a, b, n, u, v, i, j, t, cas = 1, tt, now;
get_gogo();
scanf("%d", &tt);
while(tt --)
{
scanf("%d", &n);
CLR(dp, -1);
t = a = b = 0;now = 0;
for(i = 0; i < n; i ++)
{
scanf("%d%d", &u, &v);
if(u > v) swap(u, v);
int tmd = gogo[u][v];
t += (1 << tmd);
int kao = 9 - get_f(t);
if(i & 1)
{
b += kao - now;
now = kao;
}
else
{
a += kao - now;
now = kao;
}
}
for(i = t, num = 0; i < (1 << 24); i ++)
{
if((i & t) == t)
{
mp[num ++] = i;
}
}
if(n & 1)
{
b += dfs(0);
printf("Case #%d: %s\n", cas ++, b > (9 - b) ? "Jerry404" : "Tom200");
}
else
{
a += dfs(0);
printf("Case #%d: %s\n", cas ++, a < (9 - a) ? "Jerry404" : "Tom200");
}
}
}

hdu 4753 Fishhead’s Little Game的更多相关文章

  1. HDU 4753 Fishhead’s Little Game(DFS)

    题目链接 很繁琐的爆搜,最多要加2^12条边,暴力就可以,回溯那部分一直没有回溯好,写了一晚上...代码非常,非常难看..对了,还不是普通的爆搜,双向搜索博弈,以前记得看过,这次好像第一次写.. #i ...

  2. hdu 4753 Fishhead’s Little Game 博弈论+记忆化搜索

    思路:状态最多有2^12,采用记忆化搜索!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm& ...

  3. hdu 4753 2013南京赛区网络赛 记忆化搜索 ****

    看到范围基本可以想到dp了,处理起来有点麻烦 #include<iostream> #include<cstdio> #include<cstring> #incl ...

  4. HDU 1892 See you~(二维树状数组)

    See you~ Time Limit: 5000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Others)Total Su ...

  5. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  6. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  7. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

  8. HDU 4569 Special equations(取模)

    Special equations Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u S ...

  9. HDU 4006The kth great number(K大数 +小顶堆)

    The kth great number Time Limit:1000MS     Memory Limit:65768KB     64bit IO Format:%I64d & %I64 ...

随机推荐

  1. C++ Primer 有感(异常处理)

    1.异常是通过抛出对象而引发的.该对象的类型决定应该激活哪个处理代码.被选中的处理代码是调用链中与该对象类型匹配且离抛出异常位置最近的那个. 2.执行throw的时候,不会执行跟在throw后面的语句 ...

  2. 浏览器缓存相关http头

    近期看雅虎黄金34条,学习下优化站点性能的方法. 当中有一条:"为文件头指定Expires或Cache-Control",详细来说指对于静态内容:设置文件头过期时间Expires的 ...

  3. 俄罗斯方块:win32api开发

    本文简述一门课程,演示win32api开发俄罗斯方块的开发过程.如果学生学习过C语言,没学过或者学习C++不好,刚刚開始学习win32api程序设计,还不懂消息循环和注冊窗体类.   近期的照片在这里 ...

  4. pthread_t definition

    近期在看google的chromium的代码,认为其基础库base中的对于与平台有关的线程的数据结构的定义与其代码中的凝视部分不匹配. // PlatformThreadHandle should n ...

  5. CodePen&#39;s CSS

    p{text-indent:2em;}前端开发whqet,csdn,王海庆,whqet,前端开发专家 翻译自:CodePen's CSS 翻译人员:前端开发whqet,意译为主.不当之处欢迎大家指正. ...

  6. 把Storyboard减轻的方法

    把Storyboard减轻的方法 by 伍雪颖 UIViewController *secondStoryboard = [[UIStoryboard storyboardWithName:@&quo ...

  7. TCP协议三次握手

    TCP协议三次握手过程分析 TCP(Transmission Control Protocol) 传输控制协议 TCP是主机对主机层的传输控制协议,提供可靠的连接服务,采用三次握手确认建立一个连接: ...

  8. HttpApplication事件执行顺序(转)

    HttpApplication 类的实例(Global继承自该类)是在 ASP.NET 基础结构中创建的,而不是由用户直接创建的.HttpApplication 类的一个实例在其生存期内被用于处理多个 ...

  9. jquery mobile 入门

    简介:jQuery Mobile框架可以轻松的帮助我们实现非常好看的.可跨设备的Web应用程序.我们将后续的介绍中向大家介绍大量的代码及实例. jQuery一直以来都是非常流行的富客户端及Web应用程 ...

  10. arm str 指令

    str 指令格式: str{条件} 1源寄存器 ,2存储器地址 eg: str r0,[r1],#8;将r0中的数值赋值给r1,然后在r1地址上+立即数8,再写入r1中: str r0,[r1,#8] ...