巧克力棒
總時間限制: 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.每個小朋友都...