洛谷 CF1012C Hills(動態規劃)

2022-02-02 05:02:43 字數 1928 閱讀 3237

題目大意:

有幾座山,如果一座山左右兩邊的山比它矮,那麼可以在這個山上建房子,你有一台挖掘機,每天可以挖一座山一公尺,問你需要花多少代價可以分別蓋1、2、3……座房子。(給出山的數量,以及每座山的高度)。

題目分析:

性質1:不會有兩座相鄰的山都建房子。性質 2:一座山蓋房子就不會被挖,被挖就不會蓋房子(兩條廢話)

每一座山有兩種情況:建房子或者不建,可以用一維來儲存([ 0 ]/[ 1 ])。

1到第 i 座山的代價和只與 i 前面的兩座山有關:如果這座山( i )不建,那麼他前面那座山( i-1 )可建可不建,它的代價就是前面山代價的最小值。如果這座山(i)建房,那麼它前面的那座山(i - 1)一定不建,它的代價就與前兩座山有關係。以此類推,就可以遍歷全部求最值。

我們定義乙個陣列dp[ i ] [ j ] [0/1 ]用來表示前 i 座山中建了 j 個房子的代價 ,最後一維表示當前第 i 座山是否建房子。

如果這座山選擇不蓋房子,那麼它的代價取決於前一座山的情況。

如圖:

dp[i][j][0]=min(dp[i-1][j][0],dp[i-1][j][1]+cost(i-1,i));//如果前一座山蓋房子,那麼這座山有可能挖
cost(i,j)函式表示 i 蓋房子需要挖 j 挖多少代價。

int cost(int i,int

j)else

}

如果這座山蓋房子:

如圖,這座山的代價與前面兩座山都有關。

如果 i 選擇蓋房子,那麼 i - 1 肯定蓋不了,而 i - 2蓋不蓋房子會產生影響。

如果 i - 2 不蓋房子,那就沒什麼可以擔心的,直接挖 i - 1 到比 i 矮就可以了。

如果 i - 2 蓋房子,那就要比較到底把 i - 1 挖到比誰矮。

dp[i][j][1]=min(dp[i-2][j-1][0]+cost(i,i-1),dp[i-2][j-1][1]+max(cost(i,i-1),cost(i-2,i-1)));
最後要輸出的結果,是蓋 1,2,3,……棟房子的最小代價。

首先我們需要知道最多蓋幾棟房子:

設想:一共n座山,相鄰山不能同時蓋房子,所以要麼蓋1、3、5、7……要麼蓋2、4、6、8……

最多蓋( n + 1 )/2棟房子(自己推一下,記住整形運算自動向下取整)

這樣結果就出來了,輸出相應的 min(dp[ i ][ j ][ 0 ],dp[ i ][ j ][ 1 ])即可。

全**:

#include#include

#include

#include

using

namespace

std;

const

int maxn=5010

;int dp[maxn][maxn][2

],a[maxn];

int cost(int i,int

j)else

}int

n,cnt;

intmain()

}for(int i=1;i<=n;i++)

dp[1][1][1]=0

; dp[

2][1][1]=cost(2,1

); dp[

2][1][0]=cost(1,2

);

for(int i=3;i<=n;i++)

}int cnt=(n+1)/2

;

for(int j=1;j<=cnt;j++)

printf("\n

");}

洛谷1012 拼數

設有n個正整數 n 20 將它們聯接成一排,組成乙個最大的多位整數。例如 n 3時,3個整數13,312,343聯接成的最大整數為 34331213 又如 n 4時,4個整數7,13,4,246聯接成的最大整數為 7424613 第一行,乙個正整數n。第二行,n個正整數。乙個正整數,表示最大的整數 ...

洛谷1012拼數

設有n個正整數 n 20 將它們聯接成一排,組成乙個最大的多位整數。例如 n 3時,3個整數13,312,343聯接成的最大整數為 34331213 又如 n 4時,4個整數7,13,4,246聯接成的最大整數為 7424613 把n個整數轉換為字串 str x,s x為整數 然後從大到小,最後從大...

洛谷 1012 拼數

題目描述 設有n個正整數 n 20 將它們聯接成一排,組成乙個最大的多位整數。例如 n 3時,3個整數13,312,343聯接成的最大整數為 34331213 又如 n 4時,4個整數7,13,4,246聯接成的最大整數為 7424613 輸入輸出格式 輸入格式 第一行,乙個正整數n。第二行,n個正...