30分,悬关求调
查看原帖
30分,悬关求调
1091675
乔乔2011楼主2024/12/21 21:08
#include<iostream>
#include<vector>
using namespace std;

inline int read() {
	int c = 0;
	bool f = 1;
	char ch = getchar();

	while (ch < '0' || ch > '9') {
		if (ch == '-') {
			f = 0;
		}
		ch = getchar();
	}

	while (ch >= '0' && ch <= '9') {
		c = c * 10 + ch - '0';
		ch = getchar();
	}

	return c * ((f << 1) - 1);
}

int n, m;
int map[105];

int dp[105][70][70], ans = 0;

vector<int>cango[105];

int main() {
	n = read(), m = read();

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= m; j++) {
			char f;
			cin >> f;

			if (f == 'P') {
				map[i]++;
			}
			map[i] <<= 1;
		}

		map[i] >>= 1;
	}

	cango[0].push_back(0);
	for (int i = 1; i <= n; i++) {
		for (int j = 0; j <= (1 << m) - 1; j++) {
			if ((j & (~map[i])) || (j & (j << 1)) || (j & (j << 2))) {
				continue;
			}

			cango[i].push_back(j);
		}
	}

	for (int i = 0; i < cango[1].size(); i++) {
		if ((i & (i << 1)) || (i & (i << 2))) {
			continue;
		}

		int i1 = cango[1][i], i2 = 0;

		while (i1 != 0) {
			if (i1 % 2 != 0) {
				i2++;
			}

			i1 /= 2;
		}

		dp[1][i][0] = i2;
	}

	for (int i = 0; i < cango[2].size(); i++) {
		if ((i & (i << 1)) || (i & (i << 2))) {
			continue;
		}

		for (int j = 0; j < cango[1].size(); j++) {
			int i1 = cango[2][i], j1 = cango[1][j], i2 = 0, j2 = 0;

			if (i1 & j1) {
				continue;
			}

			while (i1 != 0) {
				if (i1 % 2 != 0) {
					i2++;
				}

				i1 /= 2;
			}
			while (j1 != 0) {
				if (j1 % 2 != 0) {
					j2++;
				}

				j1 /= 2;
			}

			dp[2][i][j] = i2 + j2;
		}
	}

	for (int i = 3; i <= n; i++) {
		for (int j = 0; j < cango[i].size(); j++) {
			for (int k = 0; k < cango[i - 1].size(); k++) {
				int j1 = cango[i][j], k1 = cango[i - 1][k], j2 = 0;

				if (j1 & k1) {
					continue;
				}

				while (j1 != 0) {
					if (j1 % 2 != 0) {
						j2++;
					}

					j1 /= 2;
				}

				j1 = cango[i][j];

				int _max = 0;

				for (int l = 0; l < cango[i - 2].size(); l++) {
					int l1 = cango[i - 2][l];

					if ((l1 & j1) || (l1 & k1)) {
						continue;
					}

					_max = max(_max, dp[i - 1][k][l]);
				}

				dp[i][j][k] = j2 + _max;
			}
		}
	}

	for (int i = 0; i < cango[n].size(); i++) {
		for (int j = 0; j < cango[n - 1].size(); j++) {
			if (cango[n][i] & cango[n - 1][j]) {
				continue;
			}

			ans = max(ans, dp[n][i][j]);
		}
	}

//	for (int i = 1; i <= n; i++) {
//		cout << i << " " << map[i] << "\n";
//	}
//
//	for (int i = n; i <= n; i++) {
//		for (int j = 0; j < cango[i].size(); j++) {
//			for (int k = 0; k < cango[i - 1].size(); k++) {
//				cout << i << " " << cango[i][j] << " " << cango[i - 1][k] << " " << dp[i][j][k] << "\n";
//			}
//		}
//	}

	cout << ans;

	return 0;
}

在输出ans时,过#1,2,4,11

在输出ans + 1时,过#5,6,7,8,10,12

在输出ans + 2时,过#3,9

也就是ans比正确答案:一样/少1/少2

2024/12/21 21:08
加载中...