出於某些方面的需求,懶羊羊要把一塊n×m的蛋糕切成乙個個1×1的小蛋糕。
對於一塊蛋糕,我們只能從某條橫線或者某條豎線(要在方格線上),而且這蛋糕是不均勻的,從不同的線切割下去要花不同的代價。而且,對於一塊蛋糕,切割一次以後就被分割成兩塊,而且不能把這兩塊蛋糕拼在一起然後一刀切成四塊,只能兩塊分別再進行一次切割。
現在,給出從不同的線切割所要花的代價,求把整塊蛋糕分割成1×1塊小方塊所需要耗費的最小代價。
輸入檔案第一行包括n和m,表示長n寬m的矩陣。
第二行包括n-1個非負整數,分別表示沿著n-1條橫線切割的代價。
第二行包括m-1個非負整數,分別表示沿著m-1條豎線切割的代價。
輸出輸出乙個整數,表示最小代價。
2 2339
提示【資料規模】
對於60%的資料,有1≤n
,m
≤100
1 ≤ n ,m≤100
1≤n,m≤
100;
對於100%的資料,有1≤n
,m
≤2000
1 ≤ n,m ≤ 2000
1≤n,m≤
2000
。回顧自己的思路,我覺得這題是:貪心+動態規劃
1.首先這題先要利用貪心判斷出:如果同為橫的切一定是越費力的越先切(越先切代價越小),豎的也是一樣,所以我們只要事先將橫的代價從大到小排序,豎的代價從大到小排序,就完成了第一步。
2.可是我們這刀先取橫的還是先取豎的呢,這就要用到dpdp
dp的思想了:dp[
i][j
]dp[i][j]
dp[i][
j]表示我們切了i
ii橫刀,j
jj豎刀,所得的最小代價.
(p sps
ps:已經切開成兩塊的木板只能分別分開操作,這樣太麻煩——我們可以將它任看做一塊,在下次切時將切的代價乘上木塊數即可.)
橫著切代價:h[i
]∗(j
+1
)h[i]* (j+1)
h[i]∗(
j+1)
豎著切代價:s[i
]∗(i
+1
)s[i]* (i+1)
s[i]∗(
i+1)
於是,狀態轉移方程為:dp[
i][j
]=mi
n(dp
[i−1
][j]
+h[i
]∗(j
+1),
dp[i
][j−
1]+s
[i]∗
(i+1
)dp[i][j]=min(dp[i-1][j]+h[i]* (j+1),dp[i][j-1]+s[i]* (i+1)
dp[i][
j]=m
in(d
p[i−
1][j
]+h[
i]∗(
j+1)
,dp[
i][j
−1]+
s[i]
∗(i+
1)c od
e:
code:
code
:
#include
#define n 2005
using
namespace std;
bool
cmp(
int a,
int b)
int h[n]
,s[n]
,dp[n]
[n],n,m;
//這裡陣列開得比較大,記憶體有17744kb qaq
intmain()
切蛋糕(貪心 or 優先佇列)
第一行包括兩個數t,n,表示有n個蛋糕,最小的蛋糕的質量與最大的蛋糕的質量的比值不小於t 接下來n行,每行乙個數wi,表示n個蛋糕的質量輸出包括一行,為最小切割的刀數 資料保證切割次數不超過500示例1 0.99 3 2000 3000 4000 6 0.5 t 1 1 n 1000 1 wi 10...
蛋糕(區間DP) 東方記者(普通DP)
最近考試總是dp簽到題,本身就是個弱項,寫個小結 為了簡化問題 名稱 先宣告 我 是第乙個拿蛋糕的那個人 我 想要得到最大值 定義 dp i j 表示取完區間 i,j 我能得到的最大值並且最後一次是我取走的 考慮如何轉移 對答案有貢獻的區間長度為奇數 因為根據定義要保證最後一次是我取的 最後一次我取...
搖錢樹 dp 貪心
搖錢樹time limit 1000ms memory limit 1000k total submissions 106 accepted 33 description cpg 正在遊覽乙個夢中之城,在這個城市中有n棵搖錢樹。這下,可讓cpg看傻了。可是cpg只能在這個城市中呆k天,但是現在搖錢樹...