HDU 2517 棋盘分割(DP)

思路:dp[n][x1][y1][x2][y2],表示还剩n刀可以切,当前矩形位置为左上角(x1,y1), 右下角(x2,y2),

然后把公式转化下,其实就是求平方和最小


代码:

#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
using namespace std;

const int N = 10;
const double INF = 1e18;

int n, vis[15][N][N][N][N];
double num[N][N], sum[N][N], dp[15][N][N][N][N];

double get(int x1, int y1, int x2, int y2) {
	double tmp = sum[x2][y2] - sum[x1 - 1][y2] - sum[x2][y1 - 1] + sum[x1 - 1][y1 - 1];
	tmp *= tmp;
	return tmp;
}

double dfs(int n, int x1, int y1, int x2, int y2) {
	if (vis[n][x1][y1][x2][y2]) return dp[n][x1][y1][x2][y2];
	vis[n][x1][y1][x2][y2] = 1;
	double &ans = dp[n][x1][y1][x2][y2];
	ans = INF;
	if (n == 1) return ans = get(x1, y1, x2, y2);
	for (int i = x1; i < x2; i++) {
		ans = min(ans, dfs(n - 1, i + 1, y1, x2, y2) + get(x1, y1, i, y2));
		ans = min(ans, dfs(n - 1, x1, y1, i, y2) + get(i + 1, y1, x2, y2));
	}
	for (int i = y1; i < y2; i++) {
		ans = min(ans, dfs(n - 1, x1, i + 1, x2, y2) + get(x1, y1, x2, i));
		ans = min(ans, dfs(n - 1, x1, y1, x2, i) + get(x1, i + 1, x2, y2));
	}
	return ans;
}

int main() {
	while (~scanf("%d", &n)) {
		for (int i = 1; i <= 8; i++)
			for (int j = 1; j <= 8; j++) {
				scanf("%lf", &num[i][j]);
				sum[i][j] = sum[i - 1][j] + sum[i][j - 1] - sum[i - 1][j - 1] + num[i][j];
			}
		memset(vis, 0, sizeof(vis));
		printf("%.3lf\n", sqrt(dfs(n, 1, 1, 8, 8) / n - (sum[8][8] * sum[8][8] / n / n)));
 	}
	return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值