輸入格式:
第一行為乙個整數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,表示測試例項的個數,每個測試例項的第一行是乙個整...