70分求助
查看原帖
70分求助
141335
qwq2519楼主2020/10/24 14:24
#include<bits/stdc++.h>
#define rep(i,j,k) for(register int i(j);i<=k;++i)
#define drp(i,j,k) for(register int i(j);i>=k;--i)
using namespace std;
const int inf=0xfffffff;

template<typename T>
inline void read(T &x)
{
	x=0;
	int w=0;
	char register ch=getchar();
	while(ch>'9'||ch<'0')
		{
			w|=ch=='-';
			ch=getchar();
		}
	while(ch>='0'&&ch<='9')
		{
			x=(x*10)+(ch&15);
			ch=getchar();
		}
	w?x=~(x-1):x;
}
template<typename T>
inline void out(T x)
{
	if(x<0) putchar('-'),x=-x;
	if(x==0)
		{
			putchar('0');
			putchar('\n');
			return ;
		}
	char c[50];
	int num(0);
	while(x)
		{
			c[++num]=x%10+48;
			x/=10;
		}
	while(num) putchar(c[num--]);
	putchar('\n');
}

int n,m;
int maxn;
//int f[(1<<20)];
// n个错误 即 n个1

// f[i]  状态i 修复 的最少时间

//  初始化 f[i]=inf;  f[(1<<n)-1] =0;
// 目标状态    f[0]

int f[(1<<22)];
char BB[107][22],FF[107][22];
int cost[107];
int B1[107],B2[107],F1[107],F2[107];
//包含 B1[i]中的所有,而不包含 B2[i]中的任何   +∈B1    -∈F2[i]
// 修复错误 F1[i] 加入错误 F2[i]   -∈F1    +∈F2
int main()
{
//	freopen("cyrcyr.in","r",stdin);
//	freopen("cyrcyr.out","w",stdout);
//   cout<<(double)(sizeof f) /1024/1024;
	read(n);
	read(m);
	maxn=(1<<n)-1;
	rep(i,0,(1<<21)) f[i]=inf;
	f[maxn]=0;
	rep(i,1,m)
	{
		read(cost[i]);
		scanf("%s",BB[i]);
		rep(j,0,n-1)
		{
			if(BB[i][j]=='+') B1[i]|=(1<<(n-1-j));
			if(BB[i][j]=='-') B2[i]|=(1<<(n-1-j));
		}
		scanf("%s",FF[i]);
		rep(j,0,n-1)
		{
			if(FF[i][j]=='-') F1[i]|=(1<<(n-1-j));
			if(FF[i][j]=='+') F2[i]|=(1<<(n-1-j));
		}
//		cout<<B1[i]<<' '<<B2[i]<<' '<<F1[i]<<' '<<F2[i]<<endl;
//		system("pause");
	}

	drp(i,maxn,1)//枚举错误状态;
	{
		rep(j,1,m)
		{
			bool flag(1);
			rep(k,0,n-1)
			{
				int t=(i&(1<<(k))); //取出i第k-1位状态 
				int b1=( B1[j]&(1<<(k))   );
				int b2=( B2[j]&(1<<(k))   );
				if(    (  ( (!t)&&b1) )  ||   ( (t&&b2)   )   )
				{
					flag=0;
					break;
				}
			}
			if(!flag) continue;
			int now=i;
			rep(k,0,n-1)
			{
			  if( F1[j]&(1<<k)  )
			  {
			  	now=  now&( ~(1<<k) );
			  }
			  if(F2[j]&(1<<k) )	
			  {
			  	now=now|(1<<k);
			  }
			}
			f[now]=min(f[now],f[i]+cost[j]);
		}
	}
	if(f[0]>=inf) cout<<0;
	else
	out(f[0]);
	return 0;
//	cout<<f[0];
}

用了很久写出的状压 发现两WA一TLE。。。。

有后效性的dp很少见啊。。为什么大家都想到图论。

2020/10/24 14:24
加载中...