題目大意:
有幾座山,如果一座山左右兩邊的山比它矮,那麼可以在這個山上建房子,你有一台挖掘機,每天可以挖一座山一公尺,問你需要花多少代價可以分別蓋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個正...