巧克力棒(記憶化搜尋)

2021-08-25 06:02:05 字數 1592 閱讀 8005

巧克力棒

總時間限制: 2000ms 記憶體限制: 65536kb

描述

有乙個n*m(1≤n,m≤30)的矩形巧克力,每一次都可以橫向或者縱向切,且每次切的花費為所切邊長的平方。問最後得到面積為k個單位巧克力(k≤=min(n*m,50))的最小花費是多少?

舉例:有乙個2*3的矩形巧克力,你可以橫向切,就可以得到2個1*3的巧克力,花費為32=9;你也可以縱向切,就可以得到1個2*1的巧克力和1個2*2的巧克力,花費為22=4。

輸入

第一行乙個整數t,代表樣例個數。

接下來的t行,每一行包括三個整數n,m,k,分別代表巧克力的尺寸,想得到的巧克力尺寸。

輸出

乙個整數,代表每一行輸入的最小花費。

樣例輸入

4

2 2 1

2 2 3

2 2 2

2 2 4

樣例輸示

554

1

【樣例1解釋】

對於樣例1中的第一組操作(2 2 1)

需要進行如下操作:

1、將2*2的巧克力切成2*1,花費是2^2=4

2、將2*1的巧克力切成1*1,花費是1^2=1

最小花費為:22+12=5

【資料規模】

1≤t≤40910

1≤n,m≤30,1≤k≤min(n*m,50)

思路點拔:本題可用一看就是深搜,但單純的深搜,絕對會超時,但是我們可以記憶化搜尋,由於本題有三個引數,所以需要乙個三維陣列記錄切割的巧克力的狀態,我們可以發現,如果把這個巧克力棒當成乙個矩形,不難發現,有兩種切法:沿著長切,沿著寬切,所以我們就要比較這兩種切法哪個花費更少,但這種做法在超時邊緣(1700~1900ms),雖然對,但是我們可以進行剪枝,不難發現,切左半部分與切右半部分是一樣的,所以就可以迴圈次數就會縮短一半,執行時間在900~1100ms。這樣說還是感覺很抽象,上**!!!

#include

#include

using

namespace

std;

const

int max=0x3f3f3f3f; //這是乙個極大數的表示方法

int dp[35][35][55],ans;

int dfs(int x,int y,int z)//深搜

if(dp[x][y][z])return dp[x][y][z]; //記憶化搜尋

int ans=max;//將ans賦值為極大值,注意,這裡不要用int_max,不然會**!!!

for(int i=1;i<=x/2;i++) //縱向切

}for(int i=1;i<=y/2;i++) //橫向切

}return dp[x][y][z]=ans; //返回結果

}int main()

return

0;}

動態規劃,記憶化搜尋(分享巧克力,LA 4794)

能想到是那種列舉子集的動態規劃,結果寫著寫著成了模擬了 s是位向量,代表著巧克力的集合。dp s 是乙個vector,裡面裝著巧克力集合s能拼出的長方形。模擬轉移方程就是列舉s的子集s0,s1,然後拼出乙個長方形,然後排序去重。果斷超時。其實這種o不ok的問題,狀態轉移方程都是一旦有一種決策ok,那...

記憶化搜尋

演算法上依然是搜尋的流程,但是搜尋到的一些解用 動態規劃 的那種思想和模式作一些儲存。一般說來,動態規劃總要遍歷所有的狀態,而搜尋可以排除一些無效狀態。更重要的是搜尋還可以剪枝,可能剪去大量不必要的狀態,因此在空間開銷上往往比動態規劃要低很多。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求...

記憶化搜尋

記憶化搜尋 演算法上依然是搜尋的流程,但是搜尋到的一些解用動態規劃的那種思想和模式作一些儲存。記憶化演算法在求解的時候還是按著自頂向下的順序,但是每求解乙個狀態,就將它的解儲存下來,以後再次遇到這個狀態的時候,就不必重新求解了。例1.題目描述 給從左至右排好隊的小朋友們分糖果,要求 1.每個小朋友都...