在洛谷除样例外所有点都过,求调
查看原帖
在洛谷除样例外所有点都过,求调
680628
ast123楼主2024/3/27 19:55

rt,代码如下

#include <cstdio>
#include <iostream>
#include <ctime>
#define check1(j) (!(j & (j<<1)) && !(j & (j<<2)))
#define check2(st1, st2, st3) (!(st1 & st2) && !(st2 & st3) && !(st1 & st3))
using namespace std;
const int N = 105, M = 10;
int n, m, st[N], dp[3][1<<M][1<<M], ans, sum[1<<M];
inline int popcnt(int x){
	int cnt = 0;
	while(x){
		++cnt; x = x&(x-1);
	}
	return cnt;
}
int main(){
	scanf("%d%d", &n, &m);
	clock_t startt = clock();
	for(int i=1; i<=n; ++i){
		char ch;
		for(int j=0; j<=m; ++j){
			ch = getchar();
			if(!j) continue;
			st[i] = (st[i]<<1)+(ch == 'P');
		}
	}
	for(int i=1; i<(1<<m); ++i)
		sum[i] = popcnt(i);
	for(int j=st[1]; 1; j=(j-1)&st[1]){
		if(check1(j))
			dp[1][j][0] = dp[0][0][0]+sum[j];
		if(!j) break;
	}
	for(int j=st[2]; 1; j=(j-1)&st[2]){
		if(check1(j)){
			for(int k=st[1]; 1; k=(k-1)&st[1]){
				if(check1(k) && check2(j, k, 0))
					dp[0][j][k] = max(dp[0][j][k], dp[1][k][0]+sum[j]);
				if(!k) break;
			}
		}
		if(!j) break;
	}
	for(int i=3; i<=n; ++i){
		for(int j=st[i]; 1; j=(j-1)&st[i]){
			if(check1(j)){
				for(int k=st[i-1]; 1; k=(k-1)&st[i-1]){
					if(check1(k) && check2(j, k, 0)){
						for(int l=st[i-2]; 1; l=(l-1)&st[i-2]){
							if(check1(l) && check2(j, k, l))
								dp[i&1][j][k] = max(dp[i&1][j][k], dp[(i-1)&1][k][l]+sum[j]);
							if(!l) break;
						}
					}
					if(!k) break;
				}
			}
			if(!j) break;
		}
	}
	for(int i=st[n]; 1; i=(i-1)&st[n]){
		for(int j=st[n-1]; 1; j=(j-1)&st[n-1]){
			ans = max(ans, dp[n&1][i][j]);
			if(!j) break;
		}
		if(!i) break;
	}
	printf("%d\n", ans);
	return 0;
}
2024/3/27 19:55
加载中...