POJ-1191 棋盘分割 记忆化搜索
2013-02-26 00:18
281 查看
题目链接:http://poj.org/problem?id=1191
化简公式,然后记忆化搜索求解。a=sqrt( Σ(xi-x)^2/n ) => n*a^2=(x1-x)^2 + (x2-x)^2 + ...... + (xn-x)^2 => n*a^2=(x1^2+x2^2+......+xn^2) - 2*(x1+x2+......xn)*x + n*x^2 . 可以看出就是求分割后平方和的最小值,然后记忆化搜索就可以了,f[k][x1][y1][x2][y2]为方块(x1,y2)-(x2,y2)还需分割k次后的平方和的最小值。这里可以先求出所有方块的平方和值,使得在搜索过程中求任意方块O(1)。看一下时间复杂度上限,一共有8^4方块,每个方块最多被分割n次,最多被2*8次更新,则O(8^5*n),所以直接循环枚举都能过,但用忆化搜索可以去掉许多不必要的状态。
化简公式,然后记忆化搜索求解。a=sqrt( Σ(xi-x)^2/n ) => n*a^2=(x1-x)^2 + (x2-x)^2 + ...... + (xn-x)^2 => n*a^2=(x1^2+x2^2+......+xn^2) - 2*(x1+x2+......xn)*x + n*x^2 . 可以看出就是求分割后平方和的最小值,然后记忆化搜索就可以了,f[k][x1][y1][x2][y2]为方块(x1,y2)-(x2,y2)还需分割k次后的平方和的最小值。这里可以先求出所有方块的平方和值,使得在搜索过程中求任意方块O(1)。看一下时间复杂度上限,一共有8^4方块,每个方块最多被分割n次,最多被2*8次更新,则O(8^5*n),所以直接循环枚举都能过,但用忆化搜索可以去掉许多不必要的状态。
//STATUS:C++_AC_0MS_592KB #include<stdio.h> #include<stdlib.h> #include<string.h> #include<math.h> #include<algorithm> #include<string> #include<queue> #include<stack> #include<vector> #include<map> using namespace std; #define LL __int64 #define pii pair<int,int> #define Max(a,b) ((a)>(b)?(a):(b)) #define Min(a,b) ((a)<(b)?(a):(b)) #define mem(a,b) memset(a,b,sizeof(a)) #define lson l,mid,rt<<1 #define rson mid+1,r,rt<<1|1 #define abs(a) ((a)>0?(a):-(a)) const int N=9,INF=0x3f3f3f3f; int num ,f[15] ,sv ,s ; int n; void getsv() { int i,j,t,x1,y1,x2,y2; for(i=1;i<=8;i++){ for(j=1,t=0;j<=8;j++){ t+=num[i][j]; s[i][j]+=s[i-1][j]+t; } } for(x1=1;x1<=8;x1++) for(y1=1;y1<=8;y1++) for(x2=x1;x2<=8;x2++) for(y2=y1;y2<=8;y2++){ sv[x1][y1][x2][y2]=s[x2][y2]-s[x2][y1-1]-s[x1-1][y2]+s[x1-1][y1-1]; sv[x1][y1][x2][y2]*=sv[x1][y1][x2][y2]; } } int dfs(int x1,int y1,int x2,int y2,int cur) { if(cur==1)return sv[x1][y1][x2][y2]; int& d=f[cur][x1][y1][x2][y2]; if(d!=INF)return d; if( x2-x1+y2-y1<cur )return INF; int i; for(i=y1+1;i<=y2;i++){ d=Min(d,dfs(x1,y1,x2,i-1,cur-1)+sv[x1][i][x2][y2]); d=Min(d,dfs(x1,i,x2,y2,cur-1)+sv[x1][y1][x2][i-1]); } for(i=x1+1;i<=x2;i++){ d=Min(d,dfs(x1,y1,i-1,y2,cur-1)+sv[i][y1][x2][y2]); d=Min(d,dfs(i,y1,x2,y2,cur-1)+sv[x1][y1][i-1][y2]); } return d; } int main() { // freopen("in.txt","r",stdin); int i,j,sum=0,x1,y1,x2,y2;; double aver=0; mem(f,INF); scanf("%d",&n); for(i=1;i<=8;i++) for(j=1;j<=8;j++){ scanf("%d",&num[i][j]); sum+=num[i][j]; } aver=(double)sum/n; getsv(); dfs(1,1,8,8,n); printf("%.3lf\n",sqrt((f [1][1][8][8]-2*sum*aver)/n+aver*aver) ); return 0; }
相关文章推荐
- POJ 1191 棋盘分割(记忆化搜索)
- POJ 1191 棋盘分割 (记忆化搜索)
- poj 1191 棋盘分割 记忆化搜索
- poj1191——分割棋盘求最小均方差,记忆化搜索
- poj 1191 棋盘分割(dp + 记忆化搜索)
- POJ 1191 棋盘分割 (记忆化搜索)
- poj1191 棋盘分割(记忆化搜索)
- POJ 1191-棋盘分割(记忆化搜索)
- poj 1191棋盘分割(递归dp, 记忆化搜索)
- POJ 1191 棋盘分割
- 经典问题六.【二维的区间dp】棋盘分割 poj 1191
- POJ 1191棋盘分割
- poj&nbsp;1191&nbsp;棋盘分割&nbsp;dp
- POJ-1191-棋盘分割(动态规划)
- POJ 1191 && HDU 2517 棋盘分割(dp)
- poj-1191-棋盘分割
- POJ1191——棋盘分割
- POJ 1191 棋盘分割
- POJ-1191-棋盘分割(动态规划)
- POJ 1191 棋盘分割(DP)