poj1191(记忆化搜索)

1.这题的经典之处感觉不在记忆化搜索,而是在区域化的预处理,之前就碰到过好多这样的题目了。

s[x1,y1,x2,y2]表示从(x1,y1)到(x2,y2)的面积,可以转换为s[x2,y2]-s[x1-1,y2]-s[x1,y2-1]+s[x1-1][y1-1];其中s[x2,y2]表示从(0,0)至(x2,y2)的面积


2.代码(g++WA,c++AC),求解释!

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#define MAX 1000000000
#define N 8//!!
#define M 10
using namespace std;
//   freopen("data.in","r",stdin);
int mat[M][M],s[M][M];
int ropow[M][M][M][M][15];
void prepare()
{
	int i,j;
    s[0][0]=mat[0][0];
    for(i=1; i<N; i++)
    {
        s[0][i]=s[0][i-1]+mat[0][i];//
        s[i][0]=s[i-1][0]+mat[i][0];
    }
    for(i=1; i<N; i++)
    {
        for(j=1; j<N; j++)
        {
            s[i][j]=s[i-1][j]+s[i][j-1]-s[i-1][j-1]+mat[i][j];
        }
    }
}

int getArea(int x1,int y1,int x2,int y2)
{
    int sum=s[x2][y2];
    if(x1>0)sum-=s[x1-1][y2];
    if(y1>0)sum-=s[x2][y1-1];
    if(x1>0&&y1>0)sum+=s[x1-1][y1-1];
    return sum*sum;//
}

int dfs(int x1,int y1,int x2,int y2,int k)//x1<=x2,y1<=y2,k>=0
{
    if(ropow[x1][y1][x2][y2][k]!=-1)return ropow[x1][y1][x2][y2][k];
    if(k==0)return  ropow[x1][y1][x2][y2][k]=getArea(x1,y1,x2,y2);
    else if(x1==x2&&y1==y2)return ropow[x1][y1][x2][y2][k]=MAX;

	int i;
    ropow[x1][y1][x2][y2][k]=MAX;
    int tmp;
    for(i=x1; i<x2; i++)
    {
        tmp=dfs(x1,y1,i,y2,k-1)+getArea(i+1,y1,x2,y2);
        if(tmp<ropow[x1][y1][x2][y2][k])ropow[x1][y1][x2][y2][k]=tmp;
        tmp=getArea(x1,y1,i,y2)+dfs(i+1,y1,x2,y2,k-1);
        if(tmp<ropow[x1][y1][x2][y2][k])ropow[x1][y1][x2][y2][k]=tmp;
    }

    for(i=y1; i<y2; i++)
    {
        tmp=dfs(x1,y1,x2,i,k-1)+getArea(x1,i+1,x2,y2);
        if(tmp<ropow[x1][y1][x2][y2][k]) ropow[x1][y1][x2][y2][k]=tmp;

        tmp=getArea(x1,y1,x2,i)+dfs(x1,i+1,x2,y2,k-1);
        if(tmp<ropow[x1][y1][x2][y2][k])ropow[x1][y1][x2][y2][k]=tmp;
    }
    return ropow[x1][y1][x2][y2][k];
}
int main()
{
    //  freopen("data.in","r",stdin);
    int block;
    cin>>block;

    for(int i=0; i<N; i++)
    {
        for(int j=0; j<N; j++)cin>>mat[i][j];
    }

    prepare();

    memset(ropow,-1,sizeof(ropow));
    double ro2=dfs(0,0,N-1,N-1,block-1);//
    double tot=s[N-1][N-1];

    tot/=block;
    tot*=tot;
    double t=sqrt(ro2/block-tot );
    printf("%.3lf\n",t) ;
    return 0;
}


3.总结

1.状态方程中用到加法,而上界用了INT_MAX,结果出现了负数------以后出现负数,注意是否越界!

2.把题目输入的n当成切割次数,结果瞎调了半天!-------不知道错了哪里时就重新读一启遍题!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值