L. Xian Xiang 2019ICPC银川现场赛

https://nanti.jisuanke.com/t/42392

注意到n=18,于是可以快乐2^n*n*n dp

一开始用dfs去给同时消除第i个和第j个的所有合法状态加入他的vector中,然后遍历所有状态枚举vector转移,dfs常数太大超时了

2s都跑不过

然后用个2进制mask来记录一下哪些是冲突的,然后在转移的时候&一下看能不能转,就322ms过了

然后又是经典num[i][j]=0没有初始化,找一年错

艹,每次队友交题我都提醒long long 初始化,边界,自己训练的时候交之前总是忘记检查,还是没有养成好习惯= =

#include<bits/stdc++.h>
using namespace std;

int n,m,k,ans,tot;
struct node
{
	int x,y;
}c[20];
int dp[1<<18],val[1<<18],s[20];
int num[8][8];
int g[20][20][2];
char ch[8][8][10];

inline void prework()
{
	scanf("%d%d%d",&n,&m,&k);
	tot=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
		{
			scanf("%s",ch[i][j]+1);
			if(ch[i][j][1]!='-')
			{
				num[i][j]=++tot;
				c[tot]=node{i,j};
			}
			else
				num[i][j]=0; 
		}
	for(int i=0;i<=k;i++)
		scanf("%d",&s[i]);
	int mask,miy,mxy,cnt,ss;
	for(int i=1;i<=tot;i++)
		for(int j=i+1;j<=tot;j++)	
		{	
			cnt=0;g[i][j][0]=g[i][j][1]=0;
			for(int l=1;l<=k;l++)
			if(ch[c[i].x][c[i].y][l]==ch[c[j].x][c[j].y][l])
				cnt++;
			mask=(1<<(i-1))+(1<<(j-1));
			val[mask]=s[cnt];
			
			miy=min(c[i].y,c[j].y);mxy=max(c[i].y,c[j].y);
			ss=0;
			for(int k=miy;k<=mxy;k++)
			if(num[c[i].x][k])
				ss|=1<<(num[c[i].x][k]-1);
			for(int k=c[i].x;k<=c[j].x;k++)
			if(num[k][c[j].y])
				ss|=1<<(num[k][c[j].y]-1);
			g[i][j][0]=ss;
			ss=0;
			for(int k=c[i].x;k<=c[j].x;k++)
			if(num[k][c[i].y])
				ss|=1<<(num[k][c[i].y]-1);
			for(int k=miy;k<=mxy;k++)
			if(num[c[j].x][k])
				ss|=1<<(num[c[j].x][k]-1);
			g[i][j][1]=ss;
		}
}

inline void mainwork()
{
	for(register int i=0;i<(1<<tot);++i)
		dp[i]=-1;
	dp[(1<<tot)-1]=0;int mask;
	for(register int ss=(1<<tot)-1;ss>=0;--ss)
	{
		if(dp[ss]==-1)
			continue;
		for(register int i=0;i<tot;++i)
		if(ss>>i&1)
			for(register int j=i+1;j<tot;++j)
			if(ss>>j&1)
			{
				mask=(1<<i)+(1<<j);
				if((g[i+1][j+1][0]&ss)==mask || (ss&g[i+1][j+1][1])==mask)
				{
					dp[ss^mask]=max(dp[ss^mask],dp[ss]+val[mask]);
				}
			}
	}
}

inline void print()
{
	printf("%d\n",dp[0]);
}

int main()
{
	int t;
	scanf("%d",&t);
	for(int i=1;i<=t;i++)
	{
		prework();
		mainwork();
		print();
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liufengwei1/article/details/109252510