您的位置:首页 > 其它

POJ 1191 棋盘分割(DP)

2013-07-09 14:51 483 查看
题目链接

大体思路看,黑书。。。其他就是注意搞一个in数组,这样记忆化搜索,貌似比较快。

#include <cstdio>
#include <cstring>
#include <iostream>
#include <cmath>
using namespace std;
#define INF 0x7fffffff
int p[10][10],sum[10][10];
double dp[11][11][11][11][21];
int in[11][11][11][11][21];
double s[11][11][11][11];
int dfs(int x1,int y1,int x2,int y2,int k)
{
int i;
if(in[x1][y1][x2][y2][k])
return dp[x1][y1][x2][y2][k];
if(k == 1)
{
in[x1][y1][x2][y2][k] = 1;
return dp[x1][y1][x2][y2][k] = s[x1][y1][x2][y2];
}
else
{
double minz = INF;
for(i = x1;i < x2;i ++)
{
minz = min(dfs(x1,y1,i,y2,k-1)+s[i+1][y1][x2][y2],minz);
minz = min(dfs(i+1,y1,x2,y2,k-1)+s[x1][y1][i][y2],minz);
}
for(i = y1;i < y2;i ++)
{
minz = min(dfs(x1,y1,x2,i,k-1)+s[x1][i+1][x2][y2],minz);
minz = min(dfs(x1,i+1,x2,y2,k-1)+s[x1][y1][x2][i],minz);
}
in[x1][y1][x2][y2][k] = 1;
return dp[x1][y1][x2][y2][k] = minz;
}
}
int main()
{
int i,j,k,u,v,n,temp;
scanf("%d",&n);
temp = 0;
for(i = 1;i <= 8;i ++)
{
for(j = 1;j <= 8;j ++)
{
scanf("%d",&p[i][j]);
temp += p[i][j];
}
}
for(i = 1;i <= 8;i ++)
{
for(j = 1;j <= 8;j ++)
{
for(k = 1;k <= 8;k ++)
{
for(u = 1;u <= 8;u ++)
{
for(v = 1;v <= n;v ++)
dp[i][j][k][u][v] = INF;
}
}
}
}
for(i = 1;i <= 8;i ++)
{
for(j = 1;j <= 8;j ++)
sum[i][j] = sum[i-1][j] + sum[i][j-1] - sum[i-1][j-1] + p[i][j];
}
for(i = 1;i <= 8;i ++)
{
for(j = 1;j <= 8;j ++)
{
for(k = 1;k <= 8;k ++)
{
for(u = 1;u <= 8;u ++)
{
s[i][j][k][u] = sum[k][u]+sum[i-1][j-1]-sum[i-1][u]-sum[k][j-1];
s[i][j][k][u] *= s[i][j][k][u];
}
}
}
}
printf("%.3f\n",sqrt(dfs(1,1,8,8,n)*1.0/n-(temp*1.0/n)*(temp*1.0/n)));
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: