uva1629,Cake Slicing,记忆化搜索

同上个题一样,代码相似度极高,或者说可以直接用一个模板吧

 

dp[i,j,p,q]表示一块长为j-i+1,宽为q-p+1,左上角在位置(i,j)上的蛋糕,dp[]表示当前状态下的最优值,然后对该块蛋糕枚举每一种切法即可

 

需要注意的是,需要剪掉樱桃为0的蛋糕的情况(想了半天没想明白为啥,一开始我是认为樱桃为0了就不需要切了,该状态的最优值置为0即可,可是WA。但是感觉不剪掉他在之后的情况中也能搜出来最优的状态啊,蛋疼不已)

coding+debug:2小时左右,记忆化+dp类型第2题

/*

 * Author:  Bingo

 * Created Time:  2015/3/3 11:32:30

 * File Name: uva1629.cpp

 */

#include <iostream>

#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <string>

#include <vector>

#include <stack>

#include <queue>

#include <set>

#include <time.h>

using namespace std;

const int maxint = 1000000;

int map[25][25];

int vis[25][25][25][25];

int dp[25][25][25][25];

int n,m,total;

int fun(int i,int j,int p,int q){

    int cnt=0;

    for (int a=i;a<=j;a++)

        for (int b=p;b<=q;b++)

            if (map[a][b]) cnt++;

    return cnt;

}

int dfs(int i,int j,int p,int q){

    int &flag=vis[i][j][p][q];

    int &res=dp[i][j][p][q];

    if (flag) return res;

    else if(fun(i,j,p,q)==1) {flag=1;res=0;return res;}

    else if(fun(i,j,p,q)==0) {

           flag=1;res=maxint;return res;

    }

    else{

        res=maxint;

        for (int t=i;t<j;t++) {

            res=min(res,dfs(i,t,p,q)+dfs(t+1,j,p,q)+q-p+1);

        }

        for (int t=p;t<q;t++) {

            res=min(res,dfs(i,j,p,t)+dfs(i,j,t+1,q)+j-i+1);

        }

        flag=1;return res;

    }

}

int main () {

    int T=0; 

    while (cin>>n>>m>>total){

        T++;

        memset(map,0,sizeof(map));

        memset(vis,0,sizeof(vis));

        memset(dp,0,sizeof(dp));

        for (int i=0;i<total;i++) {

            int p,q;

            cin>>p>>q;

            p--;q--;

            map[p][q]=1;

        }

        cout<<"Case "<<T<<": ";

        cout<<dfs(0,n-1,0,m-1)<<endl;

    }

    return 0;

}
View Code

 

你可能感兴趣的:(uva)