UVa 1629 - Cake Slicing(记忆化搜索)

对每块蛋糕进行统计,若有1颗就直接返回1,2颗或以上就继续切,没有则不可行。然后继续切的话枚举每一个可以切的方法,记忆化搜索。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=25;
int n,m;
int d[maxn][maxn][maxn][maxn];
bool g[maxn][maxn];
int getnum(int u,int d,int l,int r){
bool flag=false;
for(int i=u;i<=d;++i)
for(int j=l;j<=r;++j)
if(g[i][j]){
if(flag) return 2;
else flag=true;
}
return flag;
}
int dp(int u,int dd,int l,int r){
int& k=d[u][dd][l][r];
if(k!=-1) return k;
int num=getnum(u,dd,l,r);
if(num==1) return 0;
if(!num) return inf;
k=inf;
for(int i=l;i<r;++i)
k=min(k,dp(u,dd,l,i)+dp(u,dd,i+1,r)+dd-u+1);
for(int i=u;i<dd;++i)
k=min(k,dp(u,i,l,r)+dp(i+1,dd,l,r)+r-l+1);
return k;
}
int main(){
int k,t=0;
while(~scanf("%d%d%d",&n,&m,&k)){
memset(g,0,sizeof(g));
memset(d,-1,sizeof(d));
while(k--){
int r,c;
scanf("%d%d",&r,&c);
g[r][c]=true;
}
printf("Case %d: %d\n",++t,dp(1,n,1,m));
}
return 0;
}

本文迁移自我的 CSDN博客 ,格式可能有所偏差。