洛谷 P4363 [九省联考2018]一双木棋chess 题解

mac2022-06-30  101

题目链接:https://www.luogu.org/problemnew/show/P4363

分析:

首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下的轮廓线一定是个凸包,更具体地,从棋盘的左下沿着棋盘边界或棋子轮廓线走到棋盘右上,所走的路径一定只有向上和向右两种。

代码:

#include<cstdio> using namespace std; const int maxn=25,N=1<<20,INF=0x3f3f3f3f; int f[N],n,m,nm,c[2][maxn][maxn];bool vis[N]; void Max(int &x,int y) { if(x<y) x=y; } int Run(int now,bool rt) { if(vis[now]) return -f[now]; vis[now]=true; int &ans=f[now],k=0,i,j,cur=now,cnt=0; ans=-INF; for(k=0;now&&(k<nm);k++,cnt+=i) { i=now&1,now>>=1,j=now&1; if(i&&!j) Max(ans,Run(cur^(3<<k),!rt)+c[rt][k+1-cnt][m-cnt]); } return -ans; } int main() { int i,j; scanf("%d%d",&n,&m),nm=n+m-1; for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&c[0][i][j]); for(i=1;i<=n;i++) for(j=1;j<=m;j++) scanf("%d",&c[1][i][j]); vis[((1<<m)-1)<<n]=true,printf("%d\n",-Run((1<<m)-1,0)); return 0; }

转载于:https://www.cnblogs.com/vercont/p/10210025.html

相关资源:JAVA上百实例源码以及开源项目
最新回复(0)