首页 > 其他分享 >【题解】P4363 [九省联考 2018] 一双木棋 chess

【题解】P4363 [九省联考 2018] 一双木棋 chess

时间:2023-04-27 20:33:51浏览次数:57  
标签:11 return 格子 菲菲 int 题解 木棋 -- 联考

原题链接

题目描述

菲菲和牛牛在一块 \(n\) 行 \(m\) 列的棋盘上下棋,菲菲执黑棋先手,牛牛执白棋后手。

棋局开始时,棋盘上没有任何棋子,两人轮流在格子上落子,直到填满棋盘时结束。

落子的规则是:一个格子可以落子当且仅当这个格子内没有棋子且这个格子的左侧及上方的所有格子内都有棋子。

棋盘的每个格子上,都写有两个非负整数,从上到下第 \(i\) 行中从左到右第 \(j\) 列的格子上的两个整数记作 \(a_{i,j}\) 和 \(b_{i,j}\)。

在游戏结束后,菲菲和牛牛会分别计算自己的得分:菲菲的得分是所有有黑棋的格子上的 \(a_{i,j}\) 之和,牛牛的得分是所有有白棋的格子上的 \(b_{i,j}\) 的和。

菲菲和牛牛都希望,自己的得分减去对方的得分得到的结果最大。现在他们想知道,在给定的棋盘上,如果双方都采用最优策略且知道对方会采用最优策略,那么,最终的结果如何?

题解

轮廓线DP同时维护值和当前该哪个人走。

#include<bits/stdc++.h>
using namespace std;
inline int rd(){
	int f=1,j=0;
	char w=getchar();
	while(!isdigit(w)){
		if(w=='-')f=-1;
		w=getchar();
	}
	while(isdigit(w)){
		j=j*10+w-'0';
		w=getchar();
	}
	return f*j;
}
const int N=4000010;
int n,m,suma[11][11],sumb[11][11],f[N],g[N],vis[N];
struct node{
	int k,t;
}p[N];
int tot;
inline int si(int x){
	int cnt=0;
	while(x)cnt+=(x&1),x>>=1;
	return cnt;
}
void pri(int x){
	if(!x)return ;
	pri(x>>1);
	printf("%d",x&1);
	return ;
}
signed main(){
	n=rd(),m=rd();
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)suma[i][j]=rd();
	for(int i=1;i<=n;i++)for(int j=1;j<=m;j++)sumb[i][j]=rd();
	f[(1<<n)-1]=0,g[(1<<n)-1]=(((n*m)&1)!=1),vis[(1<<n)-1]=true;
	for(int k=(((1<<n)-1)<<m);k>=0;k--){
		if(si(k)!=n)continue;
		if(k==(1<<n)-1)continue;
		int x=n+1,y=0,t=0;
		for(int j=n+m-1;j>=0;j--){
			if(k&(1<<j))x--,t+=y;
			else y++;
		}
		p[++tot]=(node){k,t};
	}
	sort(p+1,p+1+tot,[&](node a,node b){return a.t>b.t;});
	for(int t=1,k;t<=tot;t++){
		k=p[t].k;
//		pri(k),cout<<":";
		int x=n+1,y=1;
		for(int j=n+m-1;j>=0;j--){
			if(k&(1<<j))x--;
			else y++;
			if(j==0)continue;
			if(x<1||x>n||y<1||y>m)continue;
			if(!((k&(1<<j))&&!(k&(1<<(j-1)))))continue;
			int nex=k^(1<<j)^(1<<(j-1));
			g[k]=g[nex]^1;
//			cout<<"("<<x<<","<<y<<":";
//			pri(nex),cout<<"- "<<f[nex]<<" "<<((g[k])?f[nex]+suma[x][y]:f[nex]-sumb[x][y])<<")";
			if(!vis[k])f[k]=f[nex]+((g[k])?suma[x][y]:(-sumb[x][y])),vis[k]=true;
			if(g[k])f[k]=max(f[k],f[nex]+suma[x][y]);
			else f[k]=min(f[k],f[nex]-sumb[x][y]);
		}
//		cout<<"- "<<f[k]<<" "<<g[k]<<"\n";
//		pri(k),cout<<"-"<<f[k]<<" "<<g[k]<<":";
//		x=n+1,y=1;
//		for(int j=n+m-1;j>=0;j--){
//			if(k&(1<<j))x--;
//			else y++;
//			cout<<"("<<x<<","<<y<<")";
//		}
//		printf("\n");
	}
	printf("%d\n",f[(((1<<n)-1)<<m)]);
	return 0;
}

标签:11,return,格子,菲菲,int,题解,木棋,--,联考
From: https://www.cnblogs.com/flywatre/p/17360141.html

相关文章

  • BUAACTF2023 Writeup题解 by Joooook
    BUAACTF2023WriteupbyJoooook目录MiscWhichElementchatgptzhuzhuzhuzhu'srevengeScreenshotcarzymazeMCCryptoBlockCipherMathKeyExchangeWebmotaReverseoneQuiz'srevenge*SnakeMinesweepobfu可以从队名猜一下博主是哪里人(nooffline......
  • 【题解】XX Open Cup, GP of Moscow
    //createdon23.03.26目录A.AliceandBobB.BracketsC.CirclesD.DejaVuE.EasiestSumF.FunnySalesmanG.GraphColoringH.HiddenGraphI.InsectsJ.JoiningPointsA.AliceandBob对于链上的情况,异色点是一定不会选择走进同色段的(长度不小于\(2\)),因为一定不优。......
  • springboot入门时,发现Java版本与Spring boot版本无法对应导致错误的问题解决
    <?xmlversion="1.0"encoding="UTF-8"?><projectxmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/......
  • Hackpack 2023 逆向Re部分题解
    Hackpack2023-2023/4/15https://ctf2023.hackpack.club/challenges做了2题出来,其实是一题,第一题是手动逆向,第二题是脚本自动逆向主要是学习到了nclib包使用使用说明https://nclib.readthedocs.io/en/latest/netcat.htmlSpeed-Rev题目是在3分钟逆向6题第一题是直接找字符......
  • leetcode-350-两个数组的交集 II 题解
    题目给定两个数组,编写一个函数来计算它们的交集。示例1:输入:nums1=[1,2,2,1],nums2=[2,2]输出:[2,2]示例2:输入:nums1=[4,9,5],nums2=[9,4,9,8,4]输出:[4,9]说明:输出结果中每个元素出现的次数,应与元素在两个数组中出现次数的最小值一致。我们可以不考虑输出结果......
  • 2022CCPC威海站 铜牌题解 A C D E G I J 补题
    A//木桶效应#include<bits/stdc++.h>usingnamespacestd;#defineintlonglongconstintN=2e5+10;map<string,int>cham;pair<string,int>player[N];intcnt1[6];intcnt2[6];intn,m;intsum;signedmain(){cin>>n;f......
  • JOISC2016 题解
    仍然是没有做通信题。JOISC2016Day1Matryoshka俄罗斯套娃转化错了,转化成上升子序列了,然后就变成了区间LIS。实际上是LDS,那么就可以直接做了。https://qoj.ac/submission/99648JOISC2016Day1Memory2神经衰弱我们对数进行两两配对,然后把每一对都问出来。如果不存在相......
  • GLIBCXX_3.4.20 not found 问题解决【Unable to load shared library 'lib**.so'】
    前因:问题:在调用别人的so时,出现了如下问题【GLIBCXX_3.4.20notfound】Unabletoloadsharedlibrary'libdbc.so'oroneofitsdependencies.Inordertohelpdiagnoseloadingproblems,considersettingtheLD_DEBUGenvironmentvariable:/lib64/libstdc++.so.6:v......
  • ABC267G Increasing K Times 题解
    做这道题,很有感悟,发篇文。先给数列从小到大排个序。接下来设\(f_{i,j}\)表示前\(i\)个数的排列形成\(j\)个上坡的方案数。接下来考虑转移,分为插入第\(i\)个数后增加上坡和不增加上坡两种情况。对于不增加的情况,有三种可能:第\(i\)个数插入在了数列的最前端,有\(1\)......
  • 2021牛客OI赛前集训营-提高组(第二场)第三题 树数树题解
    题目描述牛牛有一棵\(n\)个点的有根树,根为\(1\)。我们称一个长度为\(m\)的序列\(a\)是好的,当且仅当:\(\foralli\in(1,m]\),\(a_i\)为\(a_{i−1}\)的祖先或\(a_{i−1}\)是\(ai\)的祖先\(\forall1\leqi\ltj\leqm,a_i\neqa_j\)你需要帮助牛牛求出最长的......