这个题当时划水,得了二十分,现在来整一整。

这个题用状压来压缩边界线,然后通过记忆化搜索进行dp。我们可以观察到,其实每次转移,就是把一个1向左移一位。最后的状态设为0。

这其中还要有一个变量来记录谁下棋,用maxmin算法,其实就是一步取max,下一步取min,然后就木有了。

ps:a-b剪枝没学,日后再学吧。

题干:

Description

菲菲和牛牛在一块n行m列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。棋局开始时,棋盘上没有任何棋子,
两人轮流在格子上落子,直到填满棋盘时结束。落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且
这个格子的左侧及上方的所有格子内都有棋子。
棋盘的每个格子上,都写有两个非负整数,从上到下第i行中从左到右第j列的格子上的两个整数记作Aij、Bij。在
游戏结束后,菲菲和牛牛会分别计算自己的得分:菲菲的得分是所有有黑棋的格子上的Aij之和,牛牛的得分是所
有有白棋的格子上的Bij的和。
菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大。现在他们想知道,在给定的棋盘上,如果双方都
采用最优策略且知道对方会采用最优策略,那么,最终的结果如何

Input

第一行包含两个正整数n,m,保证n,m≤10。
接下来n行,每行m个非负整数,按从上到下从左到右的顺序描述每个格子上的
第一个非负整数:其中第i行中第j个数表示Aij。
接下来n行,每行m个非负整数,按从上到下从左到右的顺序描述每个格子上的
第二个非负整数:其中第i行中第j个数表示Bij
n, m ≤ 10 , Aij, Bij ≤ 100000

Output

输出一个整数,表示菲菲的得分减去牛牛的得分的结果。

Sample Input

2 3
2 7 3
9 1 2
3 7 2
2 3 1

Sample Output

2

HINT

Source

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = 1e9 + ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
int n,m;
int a[][],b[][];
int f[ << ( << )];
int dfs(int sta,bool who,int n,int m)
{
if(~f[sta])
return f[sta];
f[sta] = who ? -INF : INF;
int x = n,y = ;
duke(i,,n + m - )
{
if(sta >> i & )
x--;
else
y++;
if((sta >> i & ) != )
continue;
int nxt = sta ^ ( << i);
if(who)
{
f[sta] = max(f[sta],dfs(nxt,who ^ ,n,m) + a[x][y]);
}
else
{
f[sta] = min(f[sta],dfs(nxt,who ^ ,n,m) - b[x][y]);
}
}
return f[sta];
}
int main()
{
read(n);read(m);
duke(i,,n - )
{
duke(j,,m - )
{
read(a[i][j]);
}
}
duke(i,,n - )
{
duke(j,,m - )
{
read(b[i][j]);
}
}
memset(f,0xff,sizeof(f));
f[(( << n) - ) << m] = ;
printf("%d\n",dfs(( << n) - ,,n,m));
return ;
}

最新文章

  1. CSharpGL(30)用条件渲染(Conditional Rendering)来提升OpenGL的渲染效率
  2. Js模型和封装
  3. json-jsonConfig使用
  4. Linux下iptables拦截Nginx的问题
  5. Oracle开始从Java运行时中移除JAR包
  6. java_method_Log输出日志的方法
  7. hdu 3400 Line belt
  8. (摘)Zebra打印机异常处理
  9. BZOJ 4199: [Noi2015]品酒大会( 后缀数组 + 并查集 )
  10. B二分法
  11. 【Java数据结构学习笔记之二】Java数据结构与算法之队列(Queue)实现
  12. TI Davinci DM6446开发攻略——开发环境搭建
  13. 新概念英语(1-21)Whick book
  14. Git协作流程
  15. SpaceSyntax【空间句法】之DepthMapX学习:第二篇 输出了什么东西 与 核心概念
  16. Web开发常见安全问题
  17. 第53章 结束会话端点(End Session Endpoint) - Identity Server 4 中文文档(v1.0.0)
  18. django系列7:修改404页面展示,优化模板,降低urlconf和模板之间的耦合,命名app将模板和app绑定
  19. eclipse项目名称后面括号里的名称和项目名称不一样
  20. windows升级node

热门文章

  1. html5——:hover事件触发自己的:afert伪元素事件
  2. 4th 循环结构概述和for语句的格式及其使用
  3. 集合Set、List、Map的遍历方法
  4. 如何将工程推到github上
  5. privot函数使用
  6. matlab数值数据的表示方法,输出数据以及相关函数
  7. asp.net 跨域问题
  8. 【codeforces 510A】Fox And Snake
  9. 【[Offer收割]编程练习赛12 A】歌德巴赫猜想
  10. [BZOJ1031][JSOI2007]字符加密Cipher(后缀数组)