萌新刚学OI,状压dp0分求助
查看原帖
萌新刚学OI,状压dp0分求助
113521
muyang_233楼主2020/8/10 09:01

Rt.
都快对着题解一行一行看了还没看出来/kk

#include <cstdio>
using namespace std;
int n,m;
int ans;
int res;
int a[105];
int st[1<<10+1];
int cnt[1<<10+1];
char ch[105][15];
int dp[105][75][75];
inline int lowbit(int x){
	return x&(-x);
}
inline int get1(int x){
	int res=0;
	while(x){
		++res;
		x-=lowbit(x);
	}
	return res;
}
inline void init1(){
	for (int i=0;i<(1<<m);i++){
		if ((!i&(i<<1))&&(!i&(i<<2))&&(!i&(i>>1))&&(!i&(i>>2))){
			st[++res]=i;
			cnt[res]=get1(i);
		}
	}
}
inline void init2(){
	for (int i=1;i<=res;i++){
		if (st[i]|a[1]==a[1]){
			dp[1][i][0]=cnt[i];
		}
	}
	for (int i=1;i<=res;i++){
		for (int j=1;j<=res;j++){
			if ((st[i]|a[2]==a[2])&&(st[j]|a[1]==a[1])&&(st[i]&st[j]==0)){
				dp[2][i][j]=cnt[i]+cnt[j];
			}
		}
	}
}
inline int max(int a,int b){
	return a>b?a:b;
}
int main(){
	scanf("%d%d",&n,&m);
	for (int i=1;i<=n;i++){
		scanf("%s",ch[i]+1);
		for (int j=1;j<=m;j++){
			a[i]=a[i]*2+(ch[i][j]=='P');
		}
	}
	init1();
	init2();
	for (int i=3;i<=n;i++){
		for (int j=1;j<=res;j++){
			if (st[j]|a[i]!=a[i]){
				continue;
			}
			for (int k=1;k<=res;k++){
				if ((st[k]|a[i-1]!=a[i-1])||(st[j]&st[k])){
					continue;
				}
				for (int l=1;l<=res;l++){
					if ((st[l]|a[i-2]!=a[i-2])||(st[j]&st[l])||(st[k]&st[l])){
						continue;
					}
					dp[i][j][k]=max(dp[i][j][k],dp[i-1][k][l]+cnt[j]);
				}
			}
		}
	}
	for (int i=1;i<=res;i++){
		printf("%d %d\n",st[i],cnt[i]);
	}
	for (int i=1;i<=res;i++){
		for (int j=1;j<=res;j++){
			ans=max(ans,dp[n][i][j]);
		}
	}
	printf("%d",ans);
	return 0;
}

2020/8/10 09:01
加载中...