T180751 组队赛
我们明显可以发现这是一个状压dp
由于两边都很聪明,所以每一次出人肯定会出可以打下别人的。
由此我们可以得到\(f(s1,s2,i)\)表示甲乙的状态为\(s1\),\(s2\),擂主为\(i\)时甲/乙赢。
这就是一个博弈的题目。
由于双方都非常聪明,在确定擂主的情况下,哪一方出人就确定了,而且剩下的人也是确定的,这种情况下胜负也是确定的,也就是说这样定义就可以确定下一个确定的状态了。
具体实现使用递归/dfs会好做一点
注意空间很可能会炸掉。
这是一道罕见的比标程还短的题,处理很精妙,具体看代码
#include<bits/stdc++.h>
using namespace std;
int n;
bool used[4133][4133][21],f[4133][4133][21];
char s[1001],c[1001][1001];
bool dfs(int s1,int s2,int t)//t<0乙->t>0甲
{
if(used[s1][s2][t+10])return f[s1][s2][t+10];
used[s1][s2][t+10]=1;
bool b;
if(t>0)b=1;
else b=0;
if(t<0)//甲
for(int i=1;i<=n;i++)
{
if((((1<<(i-1))&s1))||c[i][abs(t)]=='0')continue;
b=max(b,dfs(s1|(1<<(i-1)),s2,i));
}
else
for(int i=1;i<=n;i++)
{
if((((1<<(i-1))&s2))||c[abs(t)][i]=='1')continue;
b=min(b,dfs(s1,s2|(1<<(i-1)),-i));
}
f[s1][s2][t+10]=b;
return f[s1][s2][t+10];
}
int main()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>(s+1);
for(int j=1;j<=n;j++)
c[i][j]=s[j];
}
bool ans=0;
for(int i=1;i<=n;i++)
ans=max(ans,dfs(1<<(i-1),0,i));
cout<<ans;
}
本文来自博客园,作者:lei_yu,转载请注明原文链接:https://www.cnblogs.com/lytql/p/15055493.html