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
原文地址:https://www.cnblogs.com/acbingo/p/4310721.html