动态规划 :POJ 1191 棋盘分割
2010-07-10 17:21
507 查看
题目的要求是均方差最小,按照均方差的公式,可以转化为最后分割的每个矩形的平方和最小。设f(k, x1, y1, x2, y2)左上角为x1,y1,右下角为x2,y2的矩形在切割k次之后每一块的平方和。s[x1][y1][x2][y2]左上角为x1,y1,右下角为x2,y2的矩形的平方和。
由此可以写出状态转移方程:
f(k, x1, y1, x2, y2) = min{ min(f(k-1, x1, y1, a, y2)+s[a+1][y1][x2][y2], f(k-1, a, y1, x2, y2)+s[x1][y1][a][y2]) (x1<=a<x2) (横切), min(f(k-1, x1, y1, x2, b)+s[x1][b+1][x2][y2], f(k-1, x1, b+1, x2, y2)+s[x1][y1][x2][b]) (y1<=b<y2) (纵切)}
初始状态为:f(0, 0, 0, 7, 7) = 整块棋盘的平方和。(参考《算法艺术与信息学竞赛》P116)
由此可以写出状态转移方程:
f(k, x1, y1, x2, y2) = min{ min(f(k-1, x1, y1, a, y2)+s[a+1][y1][x2][y2], f(k-1, a, y1, x2, y2)+s[x1][y1][a][y2]) (x1<=a<x2) (横切), min(f(k-1, x1, y1, x2, b)+s[x1][b+1][x2][y2], f(k-1, x1, b+1, x2, y2)+s[x1][y1][x2][b]) (y1<=b<y2) (纵切)}
初始状态为:f(0, 0, 0, 7, 7) = 整块棋盘的平方和。(参考《算法艺术与信息学竞赛》P116)
#include <stdio.h> #include <math.h> #include <algorithm> using namespace std; int matrix[8][8]; int s[8][8][8][8]; int dp[15][8][8][8][8]; int cnt; double sum; double mmin(double a, double b) { return a < b ? a : b; } int main() { int x1, x2, y1, y2, k, a; double average, sum = 0; scanf("%d", &cnt); for (x1=0; x1<8; x1++) { for (y1=0; y1<8; y1++) { scanf("%d", &matrix[x1][y1]); sum += matrix[x1][y1]; } } average = sum/cnt; for (x1=0; x1<8; x1++) { for (y1=0; y1<8; y1++) { for (x2=x1; x2<8; x2++) { sum = 0; for (y2=y1; y2<8; y2++) { sum += matrix[x2][y2]; if (x2 == x1) { s[x1][y1][x2][y2] = sum; } else { s[x1][y1][x2][y2] = s[x1][y1][x2-1][y2] + sum; } dp[0][x1][y1][x2][y2] = s[x1][y1][x2][y2] * s[x1][y1][x2][y2]; } } } } int temp; for (k=1; k<=cnt-1; k++) { for (x1=0; x1<8; x1++) { for (y1=0; y1<8; y1++) { for (x2=x1; x2<8; x2++) { for (y2=y1; y2<8; y2++) { dp[k][x1][y1][x2][y2] = 2000000000; for (a=x1; a<x2; a++) { temp = mmin(dp[k-1][x1][y1][a][y2] + s[a+1][y1][x2][y2] * s[a+1][y1][x2][y2], dp[k-1][a+1][y1][x2][y2] + s[x1][y1][a][y2] * s[x1][y1][a][y2]); dp[k][x1][y1][x2][y2] = mmin(dp[k][x1][y1][x2][y2], temp); } for (a=y1; a<y2; a++) { temp = mmin(dp[k-1][x1][y1][x2][a] + s[x1][a+1][x2][y2] * s[x1][a+1][x2][y2], dp[k-1][x1][a+1][x2][y2] + s[x1][y1][x2][a] * s[x1][y1][x2][a]); dp[k][x1][y1][x2][y2] = mmin(dp[k][x1][y1][x2][y2], temp); } } } } } } double ret = sqrt((double)dp[cnt-1][0][0][7][7] / (double)cnt - average * average); printf("%.3f/n", ret); return 0; }
相关文章推荐
- poj1191 棋盘分割
- poj 1191 棋盘分割 (dp)
- POJ 1191 棋盘分割
- POJ 1191 棋盘分割
- POJ 1191 棋盘分割
- POJ 1191 棋盘分割
- 洛谷 P1436 POJ 1191 [NOI1999 D1T2] 棋盘分割
- poj 1191 棋盘分割
- poj1191——分割棋盘求最小均方差,记忆化搜索
- poj-1191-棋盘分割
- poj 1191 棋盘分割 (dfs)
- poj 1191 棋盘分割
- poj 1191 棋盘分割(dp + 记忆化搜索)
- POJ 1191 棋盘分割(DP)
- POJ 1191 棋盘分割
- poj1191 [NOI1999] 棋盘分割(dp)
- poj 1191 棋盘分割
- poj 1191 棋盘分割
- poj 1191 棋盘分割
- poj 1191 棋盘分割