P1651 塔 動態規劃

2022-04-30 10:00:10 字數 1431 閱讀 9587

輸入格式:

第一行為乙個整數n,表示木塊個數。

第二行是n個整數,表示n塊木塊的高度。

【資料規模】

對於100%的資料,n≤50,每塊木塊的高度h滿足1≤h≤500000,所有木塊的高度總和≤500000。

輸出格式:

僅乙個整數,表示能搭建的塔的最大高度,若不能搭建兩座相同高度的塔,則輸出「-1」。

輸入樣例#1:

32 3 5

輸出樣例#1:

這道題想了我好一會啊,一直往狀壓方面湊...不過一開始忽略了乙個條件,所有的木塊都要放完.

狀態需要聯絡到差值,這類要求相等的題目似乎都可以和差值聯絡上.

定義狀態:

\[f[i][j]

\]i代表當前到了第 i 個木塊,然後 j 代表此時較小值與較大值的差值.

f[i][j] 儲存的是當前較小值的值.

狀態轉移

乙個基本的方向:我們讓當前的較小值取更大,更接近較大值.

當前這個木塊有兩個走向:

給較小值:

此時我們由前乙個狀態走過來話,他們的差值會變得更小.

同時這個較小值也會變大.

此時我們的狀態轉移即為:

\[f[i][j]=max(f[i-1][j],f[i-1][j+c[i]]+c[i]);

\]給較大值

此時同理上方,但是我們需要比較當前這個 j 和 c[i] 的大小.

因為我們 f 陣列記錄的是較小值.所以不可能之前的差值為負數.

此時狀態轉移為:

1.c[i] 大於 j

\[f[i][j]=max(f[i][j],f[i-1][c[i]-j]+c[i]-j);

\]j 小於 c[i]

\[f[i][j]=max(f[i][j],f[i-1][j-c[i]]);

\]於是我們轉移便已完成.

不過這道題目還有乙個坑點,就是極小值必須賦成很小.

否則會 wa 的很慘.

#includeusing namespace std;

const int inf=19260817;

const int maxn=51;

int f[maxn][maxn*10000],sum;

int n,c[maxn*2],ans=-1;

int main()

if(f[n][0]!=0)

ans=f[n][0];

cout

}

動態規劃 數塔

如圖所示為乙個數塔,從頂部出發在每乙個節點可以選擇向左走或向右走,一直走到最底層,要求找出一條路徑,使路徑上的數值和最大。include define n 50 int data n n d n n 定義陣列data,d int n void operate for i n 1 i 1 i else...

動態規劃 塔數

有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一行是乙個整數n 1 n 100 表示數塔的高度,接下來用n行數字表示數塔,其中第i行有個i個整數,且所有的整數均在區間 0,99 內。...

數塔 動態規劃)

在講述dp演算法的時候,乙個經典的例子就是數塔問題,它是這樣描述的 有如下所示的數塔,要求從頂層走到底層,若每一步只能走到相鄰的結點,則經過的結點的數字之和最大是多少?已經告訴你了,這是個dp的題目,你能ac嗎?input 輸入資料首先包括乙個整數c,表示測試例項的個數,每個測試例項的第一行是乙個整...