poj1191 2010.4.14

来源:互联网 发布:软件技术开发合同 编辑:程序博客网 时间:2024/06/05 03:44

poj1191 2010.4.14

详解见黑书


#include <cstdio>#include <cstring>#include <cmath>#include <iostream>using namespace std;#define MAXN 9#define MAXT 16#define M 8#define MAX 9999999int sum[MAXN][MAXN];//sum[i][j],记录以 i行j列 为右下角,1行1列为左上角的方阵的和double f[MAXT][MAXN][MAXN][MAXN][MAXN];//f[k][x1][y1][x2][y2]:切k次后,得到的k+1块的总平方和的最小值int n;double ans;//计算 (x1,y1)到(x2,y2)的格子的总和int SUM(int xx1,int yy1,int xx2,int yy2){int max=sum[xx2][yy2]-sum[xx2][yy1-1]-sum[xx1-1][yy2]+sum[xx1-1][yy1-1];return max*max;}double min(double xx,double yy){if (xx<yy)return xx;else return yy;}void init(){scanf("%d",&n);int i,j,temp,s;memset(sum,0,sizeof(sum));for(i=1;i<=M;i++){for(j=1,s=0;j<=M;j++){scanf("%d",&temp);s+=temp;sum[i][j]=sum[i-1][j]+s;}}}void dpit(){memset(f,0,sizeof(f));int xx1,xx2,yy1,yy2;for(xx1=1;xx1<=M;xx1++){for(yy1=1;yy1<=M;yy1++){for(xx2=xx1;xx2<=M;xx2++){for(yy2=yy1;yy2<=M;yy2++){f[1][xx1][yy1][xx2][yy2]=SUM(xx1,yy1,xx2,yy2);}}}}int i;double tmp;for(i=2;i<=n;i++){for(xx1=1;xx1<=M;xx1++){for(yy1=1;yy1<=M;yy1++){for(xx2=xx1;xx2<=M;xx2++){for(yy2=yy1;yy2<=M;yy2++){f[i][xx1][yy1][xx2][yy2]=MAX;for(int x=xx1;x<xx2;x++){tmp=min(f[i-1][xx1][yy1][x][yy2]+SUM(x+1,yy1,xx2,yy2),f[i-1][x+1][yy1][xx2][yy2]+SUM(xx1,yy1,x,yy2));if(f[i][xx1][yy1][xx2][yy2]>tmp)f[i][xx1][yy1][xx2][yy2]=tmp;}for(int y=yy1;y<yy2;y++){tmp=min(f[i-1][xx1][yy1][xx2][y]+SUM(xx1,y+1,xx2,yy2),f[i-1][xx1][y+1][xx2][yy2]+SUM(xx1,yy1,xx2,y));if(f[i][xx1][yy1][xx2][yy2]>tmp)f[i][xx1][yy1][xx2][yy2]=tmp;}}}}}}}int main(){init();dpit();ans=sqrt(f[n][1][1][8][8]/(double)n-sum[8][8]*sum[8][8]/(double)(n*n));printf("%.3lf\n",ans);return 0;}


0 0
原创粉丝点击