UVA 11553 Grid Game (递归 or 博弈论 DP)

题目大意:

a和b在玩游戏,a每次都可以选择一行,b每次都可以选择一列。规定选完的行或者列不能再选。每次a选完第i一行后,b都可以选择第j列,然后a会得到对应(i,j)的分数。a想分数尽可能高,b想让a的分数尽可能低。每个人都play optimally,问我们a最后最高能拿多少分。

解题思路:

这里看起来像博弈论问题,我们首先按照暴力的思维,那复杂度大概是:8!* 8!,妥妥tle。这个没有给我们任何启示。接着我们可以尝试贪心,考虑以下棋盘:

1 -2 -3
-3  4 -5
-2  1  3

转载:https://www.redgreencode.com/when-not-to-simulate-a-game-uva-11553/

比如a不想让b选择2行3列的-5,他有什么方法呢?那他可不可以首先选第一行,然后诱惑b选择第三列呢?但是b也是理性人,考虑到后面有-5,他可能就会选择第二列。所以无论a怎么走,我们发现结局依然是不变的!所以这就把问题转化为退化版八皇后,复杂度在8!,选择分数最低的就可以了。

另外本题也可以按照minmax博弈来做,但是需要用状压DP,我们用16位的bitset来记录a和b的行列的轨迹。每次轮到a他只走分数最高的行,每次轮到b他只走分数最低的列,a返回走不同行时得分的最高分,b返回走不同列时得分的最低分。边界条件就是走完返回0.

废话:

看到这题,其实给了我们思路启发就是,有时候题目比较难的时候,可以通过构造更多的样例然后从暴力和贪心不断去尝试,看有没有一些思路的启发。

#include <bits/stdc++.h>
using namespace std;
const int INF=1e9;
vector<vector<int>> gra;
int ans;
int bit;
int val;
int n;
void dfs(int level){
	if(level==n){
		ans=min(ans,val);
		return ;
	}
	for(int i=0;i<n;i++){
		if(bit&(1<<i))continue;
		bit|=1<<i;
		val+=gra[level][i];
		dfs(level+1);
		bit&=~(1<<i);
		val-=gra[level][i];
	}
}
int main(){
	int cas;cin>>cas;
	while(cas--){
		cin>>n;
		gra.assign(n,vector<int>(n));
		for(int i=0;i<n;i++)
			for(int j=0;j<n;j++)
				cin>>gra[i][j];
		ans=INF;
		val=0;
		dfs(0);
		cout<<ans<<endl;
	}
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值