注意x1到x2之间有(x2-x1)-1个可切割的边,而不是(x2-x1)-2
Sample Input
3
1 1 1 1 1 1 1 3
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 0
1 1 1 1 1 1 0 3
Sample Output
1.633
入门级区间dp
#include <cstdio>
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <cstring>
#include <queue>
#include <set>
#include <vector>
#include <map>
#include <algorithm>
#include <math.h>
#include <stack>
#define INF 0x3f3f3f3f
#define IMAX 2147483646
#define LINF 0x3f3f3f3f3f3f3f3f
#define ll long long
#define ull unsigned long long
#define uint unsigned int
using namespace std;
int n, a[11][11],s[11][11];
double av;
double f[16][10][10][10][10];
double get(int x1, int y1, int x2, int y2) {
return ((s[x2][y2] + s[x1 - 1][y1 - 1] - s[x2][y1 - 1] - s[x1 - 1][y2]) - av)*
((s[x2][y2] + s[x1 - 1][y1 - 1] - s[x2][y1 - 1] - s[x1 - 1][y2]) - av);
}
double dp(int x,int x1, int y1, int x2, int y2) {
if (x == 0)
return get(x1, y1, x2, y2);
if (f[x][x1][y1][x2][y2] != 0)
return f[x][x1][y1][x2][y2];
double ans = INF;
for (int i = x1 + 1; i <= x2; i++) {
ans = min(ans, dp(x - 1, i, y1, x2, y2) + get(x1, y1, i - 1, y2));
ans = min(ans, dp(x - 1, x1, y1, i - 1, y2) + get(i, y1, x2, y2));
}
for (int i = y1 + 1; i <= y2; i++) {
ans = min(ans, dp(x - 1, x1, i, x2, y2) + get(x1, y1, x2, i - 1));
ans = min(ans, dp(x - 1, x1, y1, x2, i - 1) + get(x1, i, x2, y2));
}
f[x][x1][y1][x2][y2] = ans;
return ans;
}
int main() {
scanf("%d", &n);
av = 0;
for (int i = 1; i <= 8; i++) {
for (int j = 1; j <= 8; j++) {
scanf("%d", &a[i][j]);
av += a[i][j];
s[i][j] = a[i][j] + s[i - 1][j] + s[i][j - 1] - s[i - 1][j - 1];
}
}
av /= n;
double ans = dp(n - 1, 1, 1, 8, 8);
printf("%.3lf", sqrt(ans / n));
return 0;
}