取數問題 區間dp入門)

2021-10-07 05:54:47 字數 2179 閱讀 9018

qwq

題目描述

有一排n個數,你和小明2個人玩遊戲,每個人輪流從2端取數,每次可以從左或右取,不能從中間取。你取的所有的數的和是你的得分,小明取的所有的數的和是小明的得分。如果你先取,你最多比小明多得多少分?

輸入

第一行:乙個整數n,範圍在[0, 100]。

第二行:n個整數,每個數範圍在[1, 10000]

輸出

小明足夠聰明時,你最多多得的分數。

樣例輸入

432

91

樣例輸出

9
【樣例解釋】:

第1輪取3;

第2輪取2;

第1輪取9;

第3輪取1;

(3+9)-(2+1) = 9

老規矩,分析一下題目。

我們每次只能從左邊取數或右邊取數,不能從中間取數。

有些人就想說了,那我直接用貪心求哪個數大不就好了?這題也太水了吧。

有這思想的小盆友是錯的,如果你不信我來舉個栗子(qwq)

412

10010a[1

] a[

2] a[

3] a[

4]

來吧,分析一下。

貪心思維:

第一輪我選a[4](因為a[4]>a[1])

小明選a[3](因為a[3]>a[2])

第一輪我選a[2](因為a[2]>a[1])

小明選a[1]

小明:a[1]+a[3]=101

我:a[4]+a[2]=12

這一看就是我虧了啊!!!

所以貪心思維是不可行的,我們應該換一種。

區間dp思維:

假如我選了a[1],那麼小明就只能選a[2]或a[4]。

同理,我們先開乙個二維陣列f

ff,用j模擬起點,i模擬長度。

定義f [j

][i+

j]

f[j][i+j]

f[j][i

+j]是從左邊(j)取的最大差值和從右邊(i+j)取的最大差值,

定義 -f[j+1][i+j]+a[j] 是從左邊取的最大差值,

定義 -f[j][i+j-1]+a[i+j] 是從右邊取的最大差值。

所以f [j

][i+

j]=m

ax(−

f[j+

1][i

+j]+

a[j]

,−f[

j][i

+j−1

]+a[

i+j]

)f[j][i+j]=max(-f[j+1][i+j]+a[j],-f[j][i+j-1]+a[i+j])

f[j][i

+j]=

max(

−f[j

+1][

i+j]

+a[j

],−f

[j][

i+j−

1]+a

[i+j

])題目分析完畢,直接上**!!!

qwq

qwq

qwq

#include

//懶using

namespace std;

int n,f[

105]

[105

],a[

105]

,ans;

intmain()

qwq

區間DP 矩陣取數遊戲

試題 noip2007 提高組 問題描述 帥帥經常跟同學玩乙個矩陣取數遊戲 對於乙個給定的 n m的矩陣,矩陣中的每個元素 aij均為非負整數。遊戲規則如下 1.每次取數時須從每行各取走乙個元素,共 n個。m次後取完矩陣所有元素 2.每次取走的各個元素只能是該元素所在行的行首或行尾 3.每次取數都有...

區間DP入門

區間dp,看名字其實會聯想到劃分dp,其實兩者的關係並不大。劃分dp是從頭到尾劃分解決,並且有劃分數量,而區間dp沒有這些限制條件,可以從任意區間開始,一直擴大到整個區間。不斷遞推求解。同樣也是分兩步去做。首先 還是進行資料處理,比如用陣列sum i j 去儲存i到j的和,或者是用別的方式處理並儲存...

區間DP入門

今天學長給我們講了區間dp,當然聽得雲裡霧裡,講完之後基本處於自閉狀態,然後還是自己到大佬的部落格,然後看部落格,但是並沒有找到很詳細的部落格,所以我想自己寫一寫,大神們勿噴哈.一 定義 區間dp,顧名思義是在區間上dp,它的主要思想就是先在小區間進行dp得到最優解,然後再利用小區間的最優解合併求大...