給定 2 個正整數序列 a1, a2,序列長度分別為 l1, l2。
你可以進行以下的一次操作:
1. 選擇兩個數 k1,k2(1≤k1≤l1, 1≤k2≤l2);
2. 移去 a1 中最後 k1 個數,得到這 k1 個數的和 s1,l1 對應減少 k1;
3. 移去 a2 中最後 k2 個數,得到這 k2 個數的和 s2,l2 對應減少 k2;
此次操作的費用為:(s1-k1) * (s2-k2)。
進行以上操作直至兩個序列都為空,求最小的費用總和。
注意:序列為空當且僅當兩個序列同時為空。
第一行是兩個正整數 l1和 l2,表示 a1 與 a2 的長度。
第二行 l1 個整數,表示序列 a1[1..l1]。
第三行 l2 個整數,表示序列 a2[1..l2]。
輸出乙個整數,表示最小費用。
輸入 [複製]
3 2輸出1 2 3
1 2
2
【樣例說明】
第一次選取 k1=1,k2=1。費用為 (3-1)*(2-1) = 2。
第二次選取 k1=2,k2=1。費用為 (1+2-2)*(1-1) = 0。
所以,總費用為 2。
【資料範圍】
對 20% 的輸入資料:1≤l1,l2≤20
對 40% 的輸入資料:1≤l1≤400;1≤l2≤150
對 100% 的輸入資料:1≤l1,l2,a1[1..l1],a2[1..l2]≤5,000
很好的一道dp題·····
首先容易想到,為了消除每次sum-k中k帶來的影響,我們可以將所有元素-1,這樣每次計算的時候直接sum相乘即可····
然後考慮消除的策略···
打個比方l1=l2=4···我們如果要消除a1[l1]到a1[2]和a2[l2]到a2[3]這兩段區間的數的話···最好的策略肯定不是直接一次性消除···而是先消除a1[l1]和a2[l2]這兩個數,再消除a1[3]到a1[2]和a2[3]這兩段····因此不難發現··每次消除的話a1和a2的區間長度有乙個一定為1!
所以我們可以將區間消除轉化為要麼消除兩段末端a1[x],a2[y]中其中乙個··要麼同時消除兩個末端··且此時對答案的貢獻為a1[x]*a2[y];
得出dp方程
其中f[i][j]表示兩段分別剩餘i,j個數時的最少費用
#include#include#include
#include
#include
#include
#include
#include
#include
using
namespace
std;
const
int n=5001
;const
int inf=0x3f3f3f3f
;inline
intr()
intl1,l2,a1[n],a2[n];
intf[n][n];
intmain()
cout
<0][0]
}
筆試刷題總結
今天刷了一些筆試題,以下是刷完筆試題後看到的相關知識點的解析,做個小結。1 多型主要以兩種形式,靜態多型和動態多型,靜態多型主要實現了函式過載和運算子過載。動態多型主要實現了虛函式。虛函式是動態聯編,程式在執行的過程中確定呼叫哪乙個函式。2 int s 8 定義乙個指標陣列,該陣列中每個元素是乙個指...
Java刷題總結
public class hasstatic a.程式通過編譯,輸出結果為 x 102 b.程式通過編譯,輸出結果為 x 103 c.10行不能通過編譯.因為x星私有靜態變數 d.5行不能通過編譯.因為引用了私有靜態變數 解析 同乙個類內,private變數可以訪問,所以cd錯。由於x是static...
LeetCode刷題總結
123 4567 891011 12 元素交換 swap a 1 a 3 sort排序 sort a.begin a.end 陣列顛倒 reverse a.begin a.end 陣列元素置為0 memset a,0,a.size 陣列取值 a.push back 定義二維陣列 vector vec...