插头DP模板30分求助
查看原帖
插头DP模板30分求助
227728
冰糖鸽子TJ鸽子协会楼主2021/5/17 20:41

RT,莫名两个TLE,五个WA

只对了1,2,7


#include <bits/stdc++.h>
using namespace std;
#define M 15
#define N 300010
#define int long long
#define short CL
const int Has=299993;
char ch;
int sta[M][N],n,m,a[M][M],sc[M],b[M],now,kno=1,ex,ey;
struct short
{
	int dat[35];
};
map<int,int>f[M];
short dec(int Sta)
{
	short res;
	for(int i=0;i<=m;i++) {res.dat[i]=(Sta&3),Sta>>=2;}
	return res;
}
int com(short lin)
{
	int res=0;
	for(int i=0,base=1;i<=m;i++,base*=4) res+=base*lin.dat[i];
	return res;
}
void Add(int Key,int k)
{
	if(f[now][Key]) {f[now][Key]+=k;return;}
	f[now][Key]+=k;sc[now]++;sta[now][sc[now]]=Key;
}
int Done()
{
	Add(0,1);int ans=0,_f,up,lf;short F,oF;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			swap(now,kno);sc[now]=0;f[now].clear();
			memset(sta[now],0,sizeof sta[now]);
			for(int K=1;K<=sc[kno];K++)//枚举轮廓线状态
			{
				F=oF=dec(sta[kno][K]);_f=f[kno][sta[kno][K]];up=F.dat[j];lf=F.dat[0];
				if(!a[i][j])
				{
					if(!up&&!lf) {Add(sta[kno][K],_f);}
					continue;
				}
				if(!up&&!lf)
				{
					if(a[i+1][j]&&a[i][j+1])
					{
						F.dat[0]=2;
						F.dat[j]=1;
						Add(com(F),_f);
					}
					continue;
				}
				if(!up)
				{
					if(a[i][j+1])
					{
						Add(sta[kno][K],_f);
					}
					if(a[i+1][j])
					{
						F.dat[0]=0;F.dat[j]=lf;
						Add(com(F),_f);
					}
					continue;
				}
				if(!lf)
				{
					if(a[i+1][j])
					{
						Add(sta[kno][K],_f);
					}
					if(a[i][j+1])
					{
						F.dat[0]=up;F.dat[j]=0;
						Add(com(F),_f);
					}
					continue;
				}
				if(lf==2&&up==lf)
				{
					int Ind,fs=-1;
					for(Ind=j-1;Ind<=m;Ind++)
					{
						fs+=(F.dat[Ind]==1?1:(F.dat[Ind]==2?-1:0));
						if(!fs) break;
					}
					F.dat[0]=F.dat[j]=0,F.dat[Ind]=2;
					Add(com(F),_f);continue;
				}
				if(lf==1&&up==lf)
				{
					int Ind,fs=-1;
					for(Ind=j+1;Ind<=m;Ind++)
					{
						fs+=(F.dat[Ind]==1?-1:(F.dat[Ind]==2?1:0));
						if(!fs) break;
					}
					F.dat[0]=F.dat[j]=0,F.dat[Ind]=1;
					Add(com(F),_f);continue;
				}
				if(lf==2&&up==1)
				{
					F.dat[0]=F.dat[j]=0;
					Add(com(F),_f);continue;
				}
				if(lf==1&&up==2)
				{
					if(i!=ex||j!=ey) continue;
					F.dat[0]=F.dat[j]=0;
					for(int i=0;i<=m;i++) if(F.dat[i]) continue;
					ans+=_f;
				}
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
signed main()
{
	cin>>n>>m;
	for(int i=1;i<=n;i++)
	{
		for(int j=1;j<=m;j++)
		{
			cin>>ch;
			a[i][j]=(ch=='*'?0:1),ex=(ch=='.'?i:ex),ey=(ch=='.'?j:ey);
		}
	}
	return Done();
}

/*
4 5
.....
.....
.....
.....

Ans:14
My_ans:15
*/
2021/5/17 20:41
加载中...