您的位置:首页 > 其它

UVA 1629 二维裸区间DP dfs

2015-09-09 21:41 246 查看
/*1~n 1~m网格中有一些樱桃 每次切蛋糕使得每一块蛋糕上面恰好一个樱桃 问切割的总长度最小是多少*/
/*思路:这里就是遍历这个蛋糕 然后最小进行统计就好了*/
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<algorithm>
#include<cmath>
#include<queue>
#include<stack>
#include<map>
#include<set>
#include<vector>
using namespace std;
typedef long long ll;
#define inf 0x3f3f3f3f
#define eps 1e-10
#define maxl 25
#define mem(i,j) memset(i,j,sizeof(i))
int a[maxl][maxl];
int d[maxl][maxl][maxl][maxl];//就表示左上角到右下角区间的切割的最小长度 所以初始化为1~n+1,1~m+1

int check(int r1,int c1,int r2,int c2){//查询区间蛋糕数目
int cnt=0;
for(int i=r1;i<r2;i++){
for(int j=c1;j<c2;j++){
if(a[i][j]) cnt++;
}
}
return cnt;

}

int dfs(int r1,int c1,int r2,int c2){
if(d[r1][c1][r2][c2]!=inf) return d[r1][c1][r2][c2];//前面记忆化剪枝
int &ans=d[r1][c1][r2][c2];
int cnt=check(r1,c1,r2,c2);
if(cnt==0)return inf;   //表示出错
if(cnt==1) return 0;
if(r1>=r2-1&&c1>=c2-1) return 0;

if(r1<r2-1){
for(int i=r1+1;i<r2;i++){
ans=min(ans,c2-c1+dfs(r1,c1,i,c2)+dfs(i,c1,r2,c2));//分成俩个不服就OK
}
}

if(c1<c2-1){
for(int i=c1+1;i<c2;i++){
ans=min(ans,r2-r1+dfs(r1,c1,r2,i)+dfs(r1,i,r2,c2));
}
}
return ans;
}

int main()
{
freopen("in.txt", "r", stdin);
int n,m,k;
int t=0;
while(scanf("%d%d%d",&n,&m,&k)==3){
memset(a,0,sizeof(a));
memset(d,inf,sizeof(d));//这里求最小 所以取最大
int x,y;
for(int i=0;i<k;i++){
cin>>x>>y;
a[x][y]=1;
}
printf("Case %d: %d\n",++t,dfs(1,1,n+1,m+1));//因为这里是以1开始的 画个图就明了了
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: