状压90求助,最后一个点TLE,开O2才过
查看原帖
状压90求助,最后一个点TLE,开O2才过
714900
zyzbldnb楼主2023/1/31 11:51
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int maxn=1<<10;
int f[101][maxn+5][maxn+5];// 
char a[105][14];
int get1(int x)
{
	int ans=0;
	while(x>0)
	{
		if(x&1) ans++;
		x=x>>1;
	}
	return ans;
}
bool check(int st,int l)
{
	if(st>>1&st) return 0;  // 有相邻的
	if(st>>2&st) return 0;  //有间隔1的
	for(int i=0;st>>i;i++)
	  if( (st>>i&1 )&&a[l][i+1]=='H') return 0;  
	return 1;
}
int main()
{
    int n,m,ans=0;bool t=0;
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m;j++)
	{
    	cin>>a[i][j];
    	//if(a[i][j]=='H') t=1;
	}
	//if(!t)//无H
	//{cout<< ((n-1)/3+1)*( (m-1)/3+1);return 0;}
	
    for(int i=0;i<1<<m;i++)
    {
    	if(!check(i,1)) continue;
      f[1][i][0]=get1(i);ans=max(ans,f[1][i][0]);
	}
    for(int i=2;i<=n;i++)
    for(int j=0;j<1<<m;j++)//第i行
    for(int k=0;k<1<<m;k++)//i-1
    {
    	if(j&k || (!check(j,i))||!check(k,i-1)) continue;
    	for(int l=0;l<1<<m;l++) //i-2行状态
    	{
	      if(!check(l,i-2)||(l&j)) continue;
    	  f[i][j][k]=max(f[i-1][k][l]+get1(j),f[i][j][k]);
    	  //ans=max(ans,f[i][j][k]);
		}
	}
	for(int i=0;i<1<<m;i++)
	for(int j=0;j<1<<m;j++)
	ans=max(ans,f[n][i][j]);
	cout<<ans;
 	 return 0;
}
```cpp
2023/1/31 11:51
加载中...