【记忆化搜索】【dfs】【递归】Chocolate
生活随笔
收集整理的這篇文章主要介紹了
【记忆化搜索】【dfs】【递归】Chocolate
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Chocolate
題目大意:
有一塊巧克力(每一個單位有一定的美味值),判斷是否可以把他分為k塊美味值相等的小巧克力
原題:
題目描述
Charlie 有一塊巧克力。
這塊巧克力是矩形的,有 n 行 m 列一共 n × m 個大小相同的小塊,每一小塊都有一個美味值 ai,j。
Charlie 有 k 個朋友,他希望把巧克力分給這些朋友。
Charlie 按如下方法分配巧克力:做 k-1 次分割,每次拿出一塊巧克力,將它
沿水平或豎直方向分成兩塊矩形的巧克力。分割完成后一共有 k 塊巧克力,Charlie
會把這 k 塊巧克力一一分給他的朋友們。
一塊巧克力的美味值定義為它的所有小塊的美味值之和。Charlie 想知道是否
存在一種可行的方案,使每個朋友獲得的巧克力的美味值相等。
輸入
本題有多組測試數據。第一行一個正整數 T 表示數據組數。
對于每組測試數據:
第一行 3 個正整數表示 n, m, k。
接下來 n 行,每行 m 個正整數,表示每一小塊的美味值
輸出
對于每個測試數據,輸出一行 YES 或 NO,表示是否存在可行方案。
輸入樣例
2 1 3 2 2 1 1 2 2 3 2 3 3 1輸出樣例
YES NO解題思路:
遞歸每一塊是否能分開來,每一塊枚舉怎么切(詳情見代碼)
代碼:
#include<cstdio> #include<cstring> #include<iostream> using namespace std; int t,n,m,k,x,sum,a[30][30],f[30][30][30][30]; bool p[30][30][30][30],pp[30][30][30][30]; bool dfs(int x1,int y1,int x2,int y2) {if (f[x1][y1][x2][y2]==sum) return true;//剛好if (f[x1][y1][x2][y2]<sum) return false;//太少了if (p[x1][y1][x2][y2]) return pp[x1][y1][x2][y2];//記憶化p[x1][y1][x2][y2]=true;//記錄for (int i=x1;i<x2;++i)//橫著if (dfs(x1,y1,i,y2)&&dfs(i+1,y1,x2,y2))//都滿足return pp[x1][y1][x2][y2]=true;for (int i=y1;i<y2;++i)//豎著if (dfs(x1,y1,x2,i)&&dfs(x1,i+1,x2,y2))return pp[x1][y1][x2][y2]=true;return pp[x1][y1][x2][y2]=false;//不行 } int main() {scanf("%d",&t);for (int tt=1;tt<=t;++tt){memset(p,false,sizeof(p));scanf("%d %d %d",&n,&m,&k);for (int i=1;i<=n;++i)for (int j=1;j<=m;++j){scanf("%d",&x);a[i][j]=a[i-1][j]+a[i][j-1]-a[i-1][j-1]+x;}for (int i=1;i<=n;++i)for (int j=1;j<=m;++j)for (int i1=i;i1<=n;++i1)for (int j1=j;j1<=m;++j1)f[i][j][i1][j1]=a[i1][j1]-a[i-1][j1]-a[i1][j-1]+a[i-1][j-1];//求出每一塊sum=f[1][1][n][m]/k;//平分if (f[1][1][n][m]%k) printf("NO\n");//無法整分else if (dfs(1,1,n,m)) printf("YES\n");else printf("NO\n");} }總結
以上是生活随笔為你收集整理的【记忆化搜索】【dfs】【递归】Chocolate的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: BBC 纪录片《地球脉动 III》即将上
- 下一篇: 小米推出旗下首款嵌入式冰箱:米家冰箱十字