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

本文介绍了一种使用动态规划解决特定棋盘分割问题的方法,通过将棋盘分割成两部分并用0和1表示方向,实现了有效的路径寻找。文章详细解释了算法流程,并提供了完整的C++代码实现。

传送门

分析

我们用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;
}

转载于:https://www.cnblogs.com/yzxverygood/p/10439157.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值