POJ 1191

WA了十几发,我是five实锤了。。。

DP部分没有问题,坑点有几个

  • 关于设计DP数组时,初始化最小值设置为INF,问题是这个INF不能太小,最起码要大于6400的平方,但是也不可以太大,我最开始下意识的设置为0x7f7f7f7f,后面才发现这个数太大以至于出现了int溢出
  • 关于四舍五入小数,此前习惯性的使用%.3f,但是这个没有实现四舍五入,他会自动丢掉地位数字
  • 其实这个用递归做更好,我一开始出现的问题如果用递归+记忆化搜索其实就可以避免了

总之很心痛。。。

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <cmath>
using namespace std;

const int maxn= 20;
const int INF= 0x3f3f3f3f;

int m[10][10], s[10][10];
int dp[maxn][10][10][10][10];

int SqSum(int x1, int y1, int x2, int y2)
{
	--x1;
	--y1;
	int sm= s[x1][y1]+s[x2][y2]-s[x2][y1]-s[x1][y2];
	return sm*sm;
}
void Init()
{
	memset(dp, 0x3f, sizeof(dp));
	memset(s, 0, sizeof(s));

	for (int i= 1; i<= 8; ++i){
		int ls= 0;
		for (int j= 1; j<= 8; ++j){
			ls+= m[i][j];
			s[i][j]= s[i-1][j]+ls;
		}
	}

	for (int x1= 1; x1<= 8; ++x1){
		for (int y1= 1; y1<= 8; ++y1){
			for (int x2= x1; x2<= 8; ++x2){
				for (int y2= y1; y2<= 8; ++y2){
					int sq= SqSum(x1, y1, x2, y2);
					dp[0][x1][y1][x2][y2]= sq;
				}
			}
		}
	}
}

int main()
{
	int n;
	double sg, sg2, xav, xsm= 0.0;
	scanf("%d", &n);

	for (int i= 1; i<= 8; ++i){
		for (int j= 1; j<= 8; ++j){
			scanf("%d", &(m[i][j]));
			xsm+= m[i][j];
		}
	}
	Init();

	xav= xsm/n;

	// the range of k can be optimized
	for (int k= 1; k< n; ++k){ 	
		for (int x1= 1; x1<= 8; ++x1){
			for (int y1= 1; y1<= 8; ++y1){
				for (int x2= x1; x2<= 8; ++x2){
					for (int y2= y1; y2<= 8; ++y2){
						int a, b, tmp, sq;
						tmp= INF;

						for (int x= x1; x< x2; ++x){
							sq= dp[0][x+1][y1][x2][y2];
							a= dp[k-1][x1][y1][x][y2]+sq;
							sq= dp[0][x1][y1][x][y2];
							b= dp[k-1][x+1][y1][x2][y2]+sq;
							tmp= min(tmp, min(a, b));
						}
						for (int y= y1; y< y2; ++y){
							sq= dp[0][x1][y+1][x2][y2];
							a= dp[k-1][x1][y1][x2][y]+sq;
							sq= dp[0][x1][y1][x2][y];
							b= dp[k-1][x1][y+1][x2][y2]+sq;
							tmp= min(tmp, min(a, b));
						}

						dp[k][x1][y1][x2][y2]= tmp;
					}
				}
			}
		}
	}

	sg2= double(dp[n-1][1][1][8][8])/double(n)-xav*xav;
	sg= floor(1000*sqrt(sg2)+0.5)/1000;

	printf("%.3f\n", sg);
	return 0;
}
posted @ 2020-08-06 11:50  IdiotNe  阅读(76)  评论(0编辑  收藏  举报