为什么 DP 不对/求调
查看原帖
为什么 DP 不对/求调
908514
DHT666楼主2025/1/8 15:44

rt,用 dpi,j,i,jdp_{i,j,i',j'} 表示一个矩形能否删成和为 ss,再记录一下转移,最后搜索输出。

#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;

typedef long long LL;

const LL N = 20;

LL n, m, s;
LL a[N][N];
LL sum[N][N];
bool dp[N][N][N][N];
LL p[N][N][N][N];
LL v[N][N][N][N];
LL x[N * 2], y[N * 2], res;

inline LL get_sum(const LL & x1, const LL & y1, const LL & x2, const LL & y2) {
	return sum[x2][y2] - sum[x2][y1 - 1] - sum[x1 - 1][y2] + sum[x1 - 1][y1 - 1];
}

void dfs(const LL & i, const LL & j, const LL & ni, const LL & nj) {
	if(!dp[i][j][ni][nj] || p[i][j][ni][nj] == -1 || i > ni || j > nj) return;
	if(p[i][j][ni][nj] == 1) {
		x[++res] = 1;
		y[res] = v[i][j][ni][nj];
		dfs(i, j, v[i][j][ni][nj] - 1, nj);
		dfs(v[i][j][ni][nj] + 1, j, ni, nj);
	} else {
		x[++res] = 2;
		y[res] = v[i][j][ni][nj];
		dfs(i, j, ni, v[i][j][ni][nj] - 1);
		dfs(i, v[i][j][ni][nj] + 1, ni, nj);
	}
}

int main() {
//	freopen(".in", "r", stdin);
//	freopen(".out", "w", stdout);

	scanf("%lld%lld", &n, &m);
	for(LL i = 1; i <= n; i++) {
		for(LL j = 1; j <= m; j++) {
			scanf("%lld", &a[i][j]);
		}
	}

	scanf("%lld", &s);

	for(LL i = 1; i <= n; i++) {
		for(LL j = 1; j <= m; j++) {
			sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + a[i][j];
		}
	}

	for(LL lenx = 1; lenx <= n; lenx++) {
		for(LL leny = 1; leny <= m; leny++) {
			for(LL i = 1; i <= n; i++) {
				if(i + lenx - 1 > n) break;
				LL ni = i + lenx - 1;
				for(LL j = 1; j <= m; j++) {
					if(j + leny - 1 > m) break;
					LL nj = j + leny - 1;
					if(get_sum(i, j, ni, nj) == s) {
						dp[i][j][ni][nj] = 1;
						p[i][j][ni][nj] = -1;
						continue;
					}
					for(LL k = i + 1; k < ni; k++) {
						if(get_sum(i, j, k - 1, nj) + get_sum(k + 1, j, ni, nj) == s) {
							dp[i][j][ni][nj] = 1;
							p[i][j][ni][nj] = 1;
							v[i][j][ni][nj] = k;
							break;
						}
					}
					if(dp[i][j][ni][nj]) continue;
					for(LL k = j + 1; k < nj; k++) {
						if(get_sum(i, j, ni, k - 1) + get_sum(i, k + 1, ni, nj) == s) {
							dp[i][j][ni][nj] = 1;
							p[i][j][ni][nj] = 2;
							v[i][j][ni][nj] = k;
							break;
						}
					}
					if(dp[i][j][ni][nj]) continue;
					if(dp[i + 1][j][ni][nj]) {
						dp[i][j][ni][nj] = 1;
						p[i][j][ni][nj] = 1;
						v[i][j][ni][nj] = i;
						continue;
					}
					if(dp[i][j + 1][ni][nj]) {
						dp[i][j][ni][nj] = 1;
						p[i][j][ni][nj] = 2;
						v[i][j][ni][nj] = j;
						continue;
					}
					if(dp[i][j][ni - 1][nj]) {
						dp[i][j][ni][nj] = 1;
						p[i][j][ni][nj] = 1;
						v[i][j][ni][nj] = ni;
						continue;
					}
					if(dp[i][j][ni][nj - 1]) {
						dp[i][j][ni][nj] = 1;
						p[i][j][ni][nj] = 2;
						v[i][j][ni][nj] = nj;
						continue;
					}
				}
			}
		}
	}

	if(!dp[1][1][n][m]) {
		puts("NO");
	} else {
		puts("YES");
		dfs(1, 1, n, m);
		printf("%lld\n", res);
		for(LL i = 1;i <= res;i++ ){
			printf("%lld %lld\n", x[i], y[i]);
		}
	}

	return 0;
}
2025/1/8 15:44
加载中...