p4363 [九省联考2018]一双木棋chess

Posted yzxverygood

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了p4363 [九省联考2018]一双木棋chess相关的知识,希望对你有一定的参考价值。

传送门

分析

我们用0表示向右,1表示向上

于是可以得到一条江棋盘分为两块的线

直接dp即可

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#include<string>
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<queue>
#include<vector>
#include<set>
#include<map>
#include<stack>
using namespace std;
const int inf = 1e9+7;
int n,m,dp[3001000],a[110][110],b[110][110],M;
bool vis[3001000];
inline int work(int msk,int wh){
    if(vis[msk])return dp[msk];
    int res=wh?-inf:inf;
    vis[msk]=1;
    for(int i=0,j=n+1,k=1;i<n+m;i++){
      if(!(msk&(1<<i)))k++;
        else j--;
      if(i==n+m-1||((msk>>i)&3)!=1)continue;
      if(wh)res=max(res,work(msk^(3<<i),wh^1)+a[j][k]);
        else res=min(res,work(msk^(3<<i),wh^1)-b[j][k]);
    }
    return dp[msk]=res;
}
int main(){
    int i,j,k;
    scanf("%d%d",&n,&m);
    for(i=1;i<=n;i++)
      for(j=1;j<=m;j++)
        scanf("%d",&a[i][j]);
    for(i=1;i<=n;i++)
      for(j=1;j<=m;j++)
        scanf("%d",&b[i][j]);
    M=(1<<(n+m))-1;
    vis[((1<<n)-1)<<m]=1;
    printf("%d",work((1<<n)-1,1));
    return 0;
}

以上是关于p4363 [九省联考2018]一双木棋chess的主要内容,如果未能解决你的问题,请参考以下文章

P4363 [九省联考2018]一双木棋chess(对抗搜索+记忆化搜索)

P4363 [九省联考2018]一双木棋

[九省联考 2018]一双木棋chess

BZOJ5248九省联考2018一双木棋(搜索,哈希)

[BZOJ5248][九省联考2018]双木棋chess

[2018九省联考]一双木棋