切開蛋糕 dp 貪心

2021-10-08 05:46:33 字數 1902 閱讀 9397

出於某些方面的需求,懶羊羊要把一塊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天,但是現在搖錢樹...