hdu 7067 Just another board game(博弈

Just another board game
题意:
一棋子初始位于(1,1),A先手,A可以横移棋子,B可以竖移棋子,或者,到某人行动的时候可以立刻终止游戏。游戏执行k轮后会结束。最终棋子停留的底下的值为最终得分,A目标是最大化,B目标是最小化。求最终答案。

结论:
k = 1 k=1 k=1 时显然,答案为第一行的最大值
k k k 为偶数,答案为 m a x ( a 1 , 1 , m a x i = 1 m   c i ) max(a_{1,1},max_{i=1}^m\,c_i) max(a1,1,maxi=1mci)
k k k 为奇数,答案为 m i n ( a 1 , 1 , m i n i = 1 n   r i ) min(a_{1,1},min_{i=1}^n\,r_i) min(a1,1,mini=1nri)
推理:

不考虑直接结束游戏的操作:
k = 1 k=1 k=1 时,取第一行最大值
k > = 2 k>=2 k>=2 时,无论 k k k 取多大,我们只需要考虑最后两步即可(从最后往前推可以发现这个结论
k k k 为奇数,最后一步是先手 A,那么他会落到这一行中最大值的位置,B为了让这个最大值尽可能小,B肯定会在上一步选择所有行中最大值最小的一行。
k k k 为偶数,最后一步是后手B,那么他会落到这一列中最小值的位置,A为了让这个最小值尽可能大,A肯定会在上一步选择所有列中最小值最大的一列。

考虑直接结束游戏的操作:
如果 a 1 , 1 a_{1,1} a1,1 最大,先手可以直接结束游戏得到最大值
而无论 k k k 等于多少,每一步都会达到一个最值,终止游戏只会使得当前结果不符合自己结果

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn = 1e5 + 9;
ll n, m, k;
ll r[maxn], c[maxn];// r维护所有行中最大值,c所有列中最小值
void work()
{
	cin >> n >> m >> k;
	for(int i = 1; i <= n; ++i)	
		r[i] = 0;
	for(int i = 1; i <= m; ++i)
		c[i] = (int)1e9;
	ll y;// 存 a_{1,1}
	for(int i = 1; i <= n; ++i)	for(int j = 1; j <= m; ++j)
	{
		ll x;cin >> x;
		if(i == 1 && j == 1) y = x;
		r[i] = max(x, r[i]);
		c[j] = min(x, c[j]);// 
	}
	ll ans = 0;
	if(k == 1){
		cout << r[1] << endl;return;
	}
	else if(k & 1)
	{
		ans = 1e9;
		for(int i = 1; i <= n; ++i)
			ans = min(ans, r[i]);// B操作使得A只能选所有行中最大值最小的一个
	}
	else 
	{
		for(int i = 1; i <= m; ++i)
			ans = max(ans, c[i]);// A操作使得B只能选所有列中最小值最大的一个
	}
	cout << max(ans, y) << endl;
}
int main()
{
	ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	int T;cin>>T;while(T--)
	work();
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值