二十分大红大紫求调【玄关】
查看原帖
二十分大红大紫求调【玄关】
1115392
small_moon楼主2024/12/29 20:10
#include<bits/stdc++.h>
using namespace std;
const int N = 110, M = 12;
int n, m, p = 1, q;
int g[M];
bool vis[1 << M], put[N][1<<M];
int dp[2][1 << M][1 << M];
bool check(int k)
{
	int pre = -100;
	for (int i = 1; i <= m; i++)
	{
		if ((k & 1) == 1)
		{
			if (i - pre <= 2) return 0;
			pre = i;
		}
		k >>= 1;
	}
	return 1;
}
int f(int k)
{
	int ret = 0;
	while (k)
	{
		ret += (k & 1);
		k >>= 1;
	}
	return ret;
}
int main()
{
	ios::sync_with_stdio(0);
	cin.tie(0), cout.tie(0);
	cin >> n >> m;
	for (int i = 1; i <= n; i++)
		for (int j = 1; j <= m; j++)
		{
			char ch; cin >> ch;
			if (ch == 'P') g[i] <<= 1;
			else g[i] = (g[i] << 1) + 1;
		}
	for (int i = 0; i < (1 << m); i++)
		vis[i] = check(i);


	put[0][0] = 1;
	for (int i = 1; i <= n; i++)
		for (int j = 0; j < (1 << m); j++)
			if ((g[i] & j) == 0) put[i][j] = 1;



	for (int j = 0; j < (1 << m); j++)
		if (put[1][j] && vis[j]) dp[0][j][0] = f(j);


	for (int i = 2; i <= n; i++)
	{
		for (int j = 0; j < (1 << m); j++)
			if (put[i][j] && vis[j])
				for (int k = 0; k < (1 << m); k++)
					if (put[i - 1][k] && vis[k] && (k & j) == 0)
						for (int l = 0; l < (1 << m); l++)
							if (put[i - 2][l] && vis[l] && (j & l) == 0 && (l & k) == 0)
								dp[p][j][k] = max(dp[p][j][k], dp[q][k][l] + f(j));
		swap(p, q);
	}
	int ans = 0;
	for (int j = 0; j < (1 << m); j++)
		for (int k = 0; k < (1 << m); k++)
			ans = max(ans, dp[q][j][k]);
	cout << ans;
	return 0;
}
2024/12/29 20:10
加载中...