poj1191 棋盘分割 (DP)

题目链接:http://poj.org/problem?id=1191


//题目意思:在一个8*8的棋盘中要划分成n块,并且方差最小
//解题思路:用一个5维的数组来记录状态st[k][x1][y1][x2][y2],表示在第k次时从(x1,y1)到(x2,y2)的矩形切出的和的平方的和(就是已经分两块了,只是这个数组没表示从哪里切)。然后递归到前面一次,选择两个中的一块继续递归。

//0ms AC,代码如下:
#include
#include
#include
using namespace std;
#define min(a,b) ((a)<(b)) ? (a) : (b)


const int M =8;
int n;
int num[M+1][M+1]={0};//记录各个格子的值
int sum[M+1][M+1]={0};//记录(0,0)到(x,y)矩形的和
int st[15][M+1][M+1][M+1][M+1]; 

int sumFun(int x1,int y1,int x2,int y2)//返回矩形和的平方
{
	int temp;
	temp=sum[x2][y2]+sum[x1-1][y1-1]-sum[x1-1][y2]-sum[x2][y1-1];
	return temp*temp;
}
int dp(int k,int x1,int y1,int x2,int y2)
{
	int i,j,temp=1000000000;
	if(st[k][x1][y1][x2][y2]!=-1)//已计算过了不用再算
		return st[k][x1][y1][x2][y2];
	else if(k==1||x1==x2||y1==y2)
	{
		return st[k][x1][y1][x2][y2]=sumFun(x1,y1,x2,y2);
	}
	else 
	{
		for(i=x1;i

你可能感兴趣的:(poj1191 棋盘分割 (DP))