UVA 1629 二維裸區間DP dfs

/*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開始的 畫個圖就明瞭了
    }
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章