Northern D. Down We Dig(压缩状态)
Posted issue是fw
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Northern D. Down We Dig(压缩状态)相关的知识,希望对你有一定的参考价值。
容易想到暴力的 O ( n 2 ) O(n^2) O(n2)算法,每次对 [ 1 , i ] [1,i] [1,i]的子游戏展开记忆化搜索
定义 f [ i ] f[i] f[i]表示当前在 i i i位置操作的人是否能取得胜利
于是每次去 d f s dfs dfs后继即可,但是显然无法通过
每次相当于在有向无环图上多加了一个点和一些边,这几乎会影响之前大部分点的胜负情况
但是注意到 p o s pos pos位置出发的胜负情况之和 [ p o s + 1 , p o s + 8 ] [pos+1,pos+8] [pos+1,pos+8]的胜负情况相关
若 [ p o s + 1 , p o s + 8 ] [pos+1,pos+8] [pos+1,pos+8]的胜负情况确定,那么 [ 1 , p o s ] [1,pos] [1,pos]的胜负情况都被唯一确定,可以直接返回答案
所以我们引入记忆化,定义 f [ i ] [ m a s k ] f[i][mask] f[i][mask]表示从 i i i出发, [ i + 1 , i + 8 ] [i+1,i+8] [i+1,i+8]的胜负情况状压为 m a s k mask mask
此时从点 1 1 1出发的胜负情况如何
这样状态只有 n ∗ 2 m n*2^m n∗2m,可以通过
#include <bits/stdc++.h>
using namespace std;
const int maxn = 3e5+10;
int n,f[maxn][1<<8];
char a[maxn][9];
int isok(int l,int r)
{
int ans = 0;
for(int i=1;i<=8;i++)
if( a[l][i]==a[r][i] ) ans++;
return ans;
}
//f[i][j]表示[i+1,i+8]出发的胜负情况已经确定时,1出发的胜负情况
int dfs(int u,int state)
{
if( f[u][state]!=-1 ) return f[u][state];
int ok = 0;
for(int i=1;i<=8;i++)
if( isok(u,u+i)>=i && ((state>>(i-1))&1)==0 ) ok = 1;//存在胜利的可能
//二进制位从低到高分别是[i+1,i+8]
int temp = state-((1<<7)&state);
if( u==1 ) return f[u][state] = ok;
else return f[u][state] = dfs(u-1,(temp<<1)|ok);
}
int main()
{
memset( f,-1,sizeof f );
cin >> n;
for(int i=1;i<=n;i++) scanf("%s",a[i]+1 );
for(int ed=1;ed<=n;ed++)
printf("%d",(dfs(ed,(1<<8)-1 )^1)+1 );//为零表示必败状态
}
以上是关于Northern D. Down We Dig(压缩状态)的主要内容,如果未能解决你的问题,请参考以下文章
Strong Tornado Hits Northern China, 6 Dead, 190 injured..(Video)
数据加密 Northern Softworks FileWard 1.5.4 MacOSX
Buffcraft——ACM ICPC 2014–2015, NEERC, Northern Subregional Contest-B(模拟)