刚学动规的萌新求助qwq调了一上午了qwq
查看原帖
刚学动规的萌新求助qwq调了一上午了qwq
130125
冬天的雨楼主2022/2/8 11:21

萌新求助,舅舅孩子!!!QWQ

一道典型的状压DP, 挺想知道发生肾么事了。。。和第一篇题解几乎没有差别但是就是RE,TLE,WA。。。

做了一上午了。。。

#include<cstdio>
#include<cstring>
#include<string>
#include<iostream>
using namespace std;
int n,m;
int dp[3][1025][1025];
int s[1025];
int lzy[114514];
int gt1(int x){
	int cnt=0;
	while(x){
		if(x&1){
			cnt++;
		}
		x>>=1;
	}
	return cnt;
}
int main(){
	memset(dp,0,sizeof(dp));
	memset(s,0,sizeof(s));
	scanf("%d%d",&n,&m);
	for(int i=0;i<n;i++){
		char ch[114];
		cin>>ch;
		for(int j=0;j<m;j++){
			s[i]<<=1;
			if(ch[j]=='P'){
				s[i]++;
			}
		}
		//printf("%d\n",gt1(s[i]));
	}
	for(int i=0;i<(1<<m);i++){
		lzy[i]=gt1(i);
		if(!( (i&s[0]) || (i&(i<<1)) || (i&(i<<2)))){
			dp[0][0][i]=lzy[i];
		}
	}
	for(int i=0;i<(1<<m);i++){
		for(int j=0;j<(1<<m);j++){
			if((i&s[0]) || (i&(i<<1)) || (i&(i<<2))) continue;
			if((i&j) || (j&s[1]) || ((j<<1)&j) || ((j<<2)&j)) continue;
			dp[1][i][j]=lzy[i]+lzy[j];//用的是从0开始的数组!不是从1开始!!! 
			//printf("%d %d %d\n",dp[1][i][j],lzy[i],lzy[j]);
		}
	}
	for(int i=2;i<n;i++){
		for(int j=0;j<(1<<m);j++){
			if(j&s[i-1]) continue;
			if((j<<1)&j) continue;
			if((j<<2)&j) continue;
			for(int k=0;k<(1<<m);k++){
				if(k&j) continue;
				if(k&s[i]) continue;
				if((k<<1)&k) continue;
				if((k<<2)&k) continue;
				for(int l=0;l<(1<<m);l++){
					if(l&s[i-2]) continue;
					if(l&j) continue;
					if(l&k) continue;
					if((l<<1)&l) continue;
					if((l<<2)&l) continue;
					dp[i%3][j][k]=max(dp[i%3][j][k],dp[(i-1)%3][l][k]+lzy[k]);
				}
			}
		}
	}
	int ans=0;
	for(int i=0;i<(1<<m);i++){
		for(int j=0;j<(i<<m);j++){
			ans=max(ans,dp[(n-1)%3][i][j]);
		}
	}
	printf("%d",ans);
	return 0;
}
2022/2/8 11:21
加载中...