專題十二 基礎DP1 題集

CN_swords發表於2017-05-06
專題十二 基礎DP1
DP具有的性質:最優子結構,子問題重疊,邊界,子問題獨立。

按照下面的步驟去考慮:
1、構造問題所對應的過程。
2、思考過程的最後一個步驟,看看有哪些選擇情況。
3、找到最後一步的子問題,確保符合“子問題重疊”,把子問題中不相同的地方設定為引數。
4、使得子問題符合“最優子結構”。
5、找到邊界,考慮邊界的各種處理方式。
6、確保滿足“子問題獨立”,一般而言,如果我們是在多個子問題中選擇一個作為實施方案,而不會同時實施多個方案,那麼子問題就是獨立的。
7、考慮如何做備忘錄。
8、分析所需時間是否滿足要求。
9、寫出轉移方程式。

A - Max Sum Plus Plus HDU - 1024
題意:在一組數取出m個不相交的區間,使區間和的總和最大。
題解:dp[i][j]表示取了第i個數,分為j個區間和的總和最大的值
dp[i][j] = max(dp[i-1][j]+a[i], max(dp[0……(i-1)][j-1])+a[i]);
因為dp[i][j]只和dp[][j-1]和dp[i-1][j]有關,所以只需一維陣列即可
max(dp[0……(i-1)])可以在i-1層的時候處理出來,優化時間。
http://blog.csdn.net/qq_33199236/article/details/55808998

B - Ignatius and the Princess IV HDU - 1029
水題?

C - Monkey and Banana HDU - 1069
疊放立方體,使其疊的高度最大。
dp[i] 表示以i為終點(或起點)的最大高度
1.在按底的長寬排序後,進行求最大子序列和
2.記憶化搜尋,列舉以(1~n)開頭的最大dp值
http://blog.csdn.net/qq_33199236/article/details/71270169

D - Doing Homework HDU - 1074
題意:作業超過時限,超過一天扣一分,給出n個作業及其時限和需要完成的時間,求最小扣分值和其路徑
題解: 狀態壓縮dp,本應該要想到的。其N<=15,根據選沒選壓成二進位制
因為題目要求最後方案如果多個情況以字典序排序,所以可以先將原資料先排序
然後我們發現遞迴時缺少了上一個狀態的所用時間,我先預處理出來。
設這個狀態為wi,上個狀態為wj,這個狀態和上個狀態相差的那個作業的編號為id
那麼 dp[wi] = dp[wj]+time[wj]+C[id]-D[id]。
http://blog.csdn.net/qq_33199236/article/details/56015043?locationNum=3&fps=1

E - Super Jumping! Jumping! Jumping! HDU - 1087
題意:最大遞增子序列
題解:
dp[i] 表示以i為終點的遞增子序列最大值
dp[i] = max(dp[i],dp[j]+a[i]) {j < i}
http://blog.csdn.net/qq_33199236/article/details/56024593

F - Piggy-Bank HDU - 1114
題意:裝滿揹包,但要求價值最低的完全揹包
題解:
dp[i][j] 表示在揹包大小為j中裝前i個物品最優的價值
http://blog.csdn.net/qq_33199236/article/details/56025506

G - 免費餡餅 HDU - 1176
題意:在一個座標軸上,最初處在5上,給出一些點在一些時間能得到1個餡餅,每秒能移動一格,問最大能得到的餡餅個數。
題解:數塔問題
1.
預處理mp[i][j]表示在第i秒第j處能得到幾個餡餅
dp[i][j] 表示在前i秒,人在j處能得到最大餡餅數
dp[i][j] = max(dp[i-1][j-1],dp[i-1][j],dp[i-1][j+1])+mp[i][j];
2.
dp[i][j] 表示在從i秒開始,人在j處能得到最大餡餅數
dp[i][j] = max(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1])+mp[i][j];
http://blog.csdn.net/qq_33199236/article/details/56047317

H - Tickets HDU - 1260
題意: n個人在買電影票,可以兩個相鄰的一起買,也可以單獨買,給出分別需要的時間,問需要的最短時間
題解: dp[i] 代表前i人的最小花費時間
http://blog.csdn.net/qq_33199236/article/details/56671330

I - 最少攔截系統 HDU - 1257
題解: dp[i] 代表第i個人使用的攔截導彈系統
http://blog.csdn.net/qq_33199236/article/details/56675683

J - FatMouse's Speed HDU - 1160
題意:給出n組資料,要求選擇資料,證明越胖跑的越慢(即找個最長的體重嚴格遞增而速度嚴格遞減的資料)。
題解: LIS題
先按體重排序下,然後就是LIS找最長遞減就好了
記錄路徑:
1. 記錄終點,最後倒推回去,下面程式碼用的這種方式
2. 直接在過程中記錄:dp[i].pre = j;(或者用其他陣列記錄也可)
http://blog.csdn.net/qq_33199236/article/details/56677891

K - Jury Compromise POJ - 1015
題意: n組D[j],P[j]數字,選擇m組使選擇的D[j]和與P[j]和差最小,如果和差相等,選擇D[j]和與P[j]和的總和最大的。
題解:
dp[i][j] 代表選第i個,選擇的D[]和與P[]和差為j的 最大總和。
path[i][j] 記錄前i個選擇的組。
ca[i] = D[i]-P[i];
he[i] = D[i]+P[i];
如果選擇的前i組和差無法達到j,那麼dp[i][j] = -1;
if(k 前面有路徑 && k 在前面的路徑上沒有出現)
    dp[i][j+ca[k]] = max(dp[i][j+ca[k]],dp[i-1][j]+he[k]);
j 的原有範圍應該是-20*m~20*m , 將其範圍加上20*m 變成 0~40*m;
http://blog.csdn.net/qq_33199236/article/details/59054986

L - Common Subsequence POJ - 1458
題意:求最長公共子序列
題解: LCS題
具體的思路我在其他寫51nod 1006 題解寫過。
簡單的來講:
dp[i][j] 表示在第一序列的前i個和第二序列的前j個的最長公共子序列長度
dp[i][j] = a[i] == b[j] ? dp[i-1][j-1]+1 : max(dp[i-1][j],dp[i][j-1]);
http://blog.csdn.net/qq_33199236/article/details/56678732

M - Help Jimmy POJ - 1661
題解: 首先無疑的肯定要按高度進行從高到低排序,肯定有解,那麼高度肯定加上去,再加上最少的橫向走的時間
應該有兩種決策,向左跳,向右跳
dp[i][0] 代表以i左邊為起點向左跳到達地面的距離,dp[i][1] 代表以i右邊為起點向右跳到達地面的距離
如果i平臺左能跳到j平臺:
dp[i][0] = min(dp[j][0]+a[i].l-a[j].l ,dp[j][1]+a[j].r-a[i].l) +a[i].h-a[j].h;
同理i平臺右邊。
http://blog.csdn.net/qq_33199236/article/details/56680834

N - Longest Ordered Subsequence POJ - 2533
題解:裸LIS
http://blog.csdn.net/qq_33199236/article/details/56681546

O - Treats for the Cows POJ - 3186
題意:給你一組數,可以選擇取最前面的數和最後面的數,第i次取到這個數,
就將總數加上(i*取的數),使總數最大。
題解:dp[i][j] 代表從i取到j的最大總數
dp[i][j] = max(dp[i+1][j]+a[i]*(n+i-j) , dp[i][j-1]+a[j]*(n+i-j));
http://blog.csdn.net/qq_33199236/article/details/71270845

P - FatMouse and Cheese HDU - 1078
題意: 從(0,0)出發,每次最多走k格,但每次只能往
值比它現在在的值大的格子走。
題解:dp[i][j] 代表走到(i,j)的最大總值。
dp[i][j] = max(dp[prei][prej]+mp[i][j]){i,j 是 prei,prej能走到的格子}
貢獻1T,1Wa,注意題意走K步是隻能筆直走K步,導致T。
我以為我nextx是不斷更新的,沒乘j,導致wa。
http://blog.csdn.net/qq_33199236/article/details/58132282?locationNum=1&fps=1

Q - Phalanx HDU - 2859
題意:問矩陣最大對稱矩陣(按左下角到右上角對稱)的對角線長度
題解:
設mp[i][j] 代表處於(i,j)的上面與右邊字元對稱的最長長度
dp[i][j] 代表走到(i,j)的最大對稱矩陣的對角線長度
if(mp[i][j] > dp[i-1][j+1])
    dp[i][j] = dp[i-1][j+1]+1;
else
    dp[i][j] = mp[i][j];
因為dp的遞迴方程只與i-1有關,可以化成一維陣列
http://blog.csdn.net/qq_33199236/article/details/58221777

R - Milking Time POJ - 3616
題意: 在N小時內,有M個可以得到的牛奶,在相應的時間段得到相應的牛奶,在一時間只能處理一個,
而且每次得到後要休息R時間,才能進行下一次。問最大能得到的牛奶總量。
題解:首先每個時間段都在N內,那其實就是求在m個選擇幾個得到最大。
先將結束的時間均加上R,就能處理R的問題了吧。
然後就類似疊塔問題了,排序+LIS吧
http://blog.csdn.net/qq_33199236/article/details/71271026

S - Making the Grade POJ - 3666
題意: 給出n個數字組成序列a,然後再找到一個序列b,從1至n,abs(a[i]-b[i])的總和最小,
其中序列b是非嚴格單調序列,要麼是要麼是非遞減序列,要麼是非遞增序列。
題解:分別求非嚴格遞減和非嚴格遞減的答案,取最小值
怎麼求? 非嚴格遞增:
如果陣列數字需要改變,那麼往目前陣列最大的數字變
將陣列排序存於c[];
dp[i][j]代表取第i個數,現在集合最後的數是排序後的陣列的第j個
dp[i][j] = min(dp[i-1][k])(1<=k<=j)+abs(a[i]-c[j])
http://blog.csdn.net/qq_33199236/article/details/58320195

相關文章