【课后服务】20181022切蛋糕
生活随笔
收集整理的這篇文章主要介紹了
【课后服务】20181022切蛋糕
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
權當拋磚引玉吧,掌握記搜的方法最重要。
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int n,m,k; bool book[21][21]; int cake[21][21]; int dp[21][21][21][21]; int yt(int x,int y,int w,int h)//返回蛋糕內櫻桃值;x、y表示左上角坐標,w、h表示長和寬 {int yingtao=cake[x+w][y+h]-cake[x+w][y]-cake[x][y+h]+cake[x][y];return yingtao; } int dfs(int x,int y,int w,int h)//開成int類型 { int ans=2147483647;if(dp[x][y][w][h]!=-1) return dp[x][y][w][h];//若x,y,w,h的狀態(tài)已被搜過,則返回已經保存的結果if(yt(x,y,w,h)==1) return 0;//櫻桃值為1時,代價為0(不用再切了)if(yt(x,y,w,h)==0) return 214748364;//櫻桃值為0時,代價無窮大;但在實現時,INF不能大于INT_MAX/2for(int i=1;i<w;i++) ans=min(ans,dfs(x,y,i,h)+dfs(x+i,y,w-i,h)+h);//枚舉各行for(int i=1;i<h;i++) ans=min(ans,dfs(x,y,w,i)+dfs(x,y+i,w,h-i)+w);//枚舉各列dp[x][y][w][h]=ans;//保存結果return ans; } int main() {memset(dp,-1,sizeof(dp));//初始化scanf("%d%d%d",&n,&m,&k);for(int i=1;i<=k;i++){int x,y;scanf("%d%d",&x,&y);book[x][y]=1;}for(int i=1;i<=n;i++){//前綴和for(int j=1;j<=m;j++){cake[i][j]=cake[i-1][j]+cake[i][j-1]-cake[i-1][j-1];if(book[i][j]) cake[i][j]++;}}int ans=dfs(0,0,n,m);printf("%d",ans);return 0; }記憶化搜索,其實就是動態(tài)規(guī)劃(DP)與搜索的完美結合,提高了搜索的效率,也提供了DP的道路。
所謂動態(tài)規(guī)劃,就是動態(tài)的規(guī)劃,其本質就是“狀態(tài)轉移”——從一種情況直接或間接推出其他情況。對于本題而言,就是要想清楚如何得到最小代價,是由哪幾部分組成。
so本題具體操作如下:
定義一四維數組dp,存儲在x,y,w,h的狀態(tài)下的最小代價。
定義一int類型函數dfs,其返回值即為代價。若蛋糕已有解,則直接返回現有代價。否則若當前蛋糕內櫻桃值為1,返回代價為0。若當前蛋糕內櫻桃值為0,返回代價為“無窮大”。否則繼續(xù)枚舉可供下刀的行和列,繼續(xù)對兩側進行搜索,打擂臺尋找最小代價。遍歷完所有情況后,保存當前結果并返回上一層。
小結:記憶化搜索與暴搜的最大區(qū)別在于,前者對搜索進行了優(yōu)化,對當前結果進行了記錄,避免了重復搜索。
轉載于:https://www.cnblogs.com/dong-ji-yuan/p/9845264.html
總結
以上是生活随笔為你收集整理的【课后服务】20181022切蛋糕的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Lora协议整理(第2汇报)
- 下一篇: [react] 装饰器(Decorato