動態規劃習題

2021-10-05 10:37:18 字數 3655 閱讀 4593

解題思路

**lis&lcs

拿數問題 ii

解題思路

**東東在玩遊戲「game23」。

在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出-1。

input:

輸入的唯一一行包括兩個整數n和m(1<=n<=m<=5*10^8).

output:

輸出從n轉換到m的操作次數,否則輸出-1.

1.

12051840

2.42

423.

4872

1.72.

03.-1

對於這個題,如果n能轉換成m,那麼m必是n的整數倍,所以我們可以通過乙個求餘操作來進行確定,如果不是,則輸出-1。如果是,則就判斷能否通過若干次操作得到它。由於進行若干次操作實質上就是將n放大了多少倍,則我們可以先計算出m是n的多少倍,然後在一次進行對3求餘或對2求餘操作,如果沒有餘數,則可以通過一步操作到達,操作次數加一,否則不能得到,輸出-1。

#include

using

namespace std;

intmain()

else

if(temp%2==

0)//將倍數對2求餘

else}if

(count!=0)

cout

}

東東有兩個序列a和b。

他想要知道序列a的lis和序列ab的lcs的長度。

注意,lis為嚴格遞增的,即a1input:

第一行兩個數n,m(1<=n<=5,000,1<=m<=5,000)

第二行n個數,表示序列a

第三行m個數,表示序列b

output:

輸出一行資料ans1和ans2,分別代表序列a的lis和序列ab的lcs的長度

若要在n個整數中求最長上公升序列,我們可以定義乙個陣列fif_

fi​來表示以aia_

ai​為結尾的最長上公升序列,在求解fif_

fi​時,則是要遍歷其前面的元素,找到乙個最大並且的fjf_

fj​並且aja_

aj​要小於aia_

ai​,則我們可以得出fi=

fj+1

f_=f_+1

fi​=fj

​+1。最後的答案為fif_

fi​中的最大值。

對於求兩個序列的最長公共子串行,和上一方法類似,我們可以通過乙個二維陣列f[i

][j]

f[i][j]

f[i][j

]來表示a1,

a2,.

..,a

ia_,a_,...,a_

a1​,a2

​,..

.,ai

​和b1,b

2,..

.,bj

b_,b_,...,b_

b1​,b2

​,..

.,bj

​的lcs長度,如果在進行遍歷時,遇到ai=

=b

ja_==b_

ai​==b

j​,則f [i

][j]

=f[i

−1][

j−1]

+1

f[i][j]=f[i-1][j-1]+1

f[i][j

]=f[

i−1]

[j−1

]+1,即其上乙個相等狀態加1,否則,f[i

][j]

=max

(f[i

−1][

j],f

[i][

j−1]

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

f[i][j

]=ma

x(f[

i−1]

[j],

f[i]

[j−1

]),為其相鄰兩個狀態的最大值。最終的答案為f[n

][m]

f[n][m]

f[n][m

]。

#include

#include

using

namespace std;

int n,m;

int a[

5010

],b[

5010

],f[

5010];

int d[

5010][

5010];

intmain()

} f[i]

=mx+1;

} d[1]

[0]=d[0]

[0]=d[0]

[1]=

0;//求解最長公共序列

for(

int i=

1;i<=n;i++)}

int mxlis=0;

for(

int i=

1;i<=n;i++

) cout<" "<[m]

}

給乙個序列,裡邊有 n 個數,每一步能拿走乙個數,比如拿第 i 個數, ai = x,得到相應的分數 x,但拿掉這個 ai 後,x+1 和 x-1 (如果有 aj = x+1 或 aj = x-1 存在) 就會變得不可拿(但是有 aj = x 的話可以繼續拿這個 x)。求最大分數。

input:

第一行包含乙個整數 n (1 ≤ n ≤ 105),表示數字裡的元素的個數

第二行包含n個整數a1, a2, …, an (1 ≤ ai ≤ 105)

output:

輸出乙個整數:n你能得到最大分值。

1:21

22:31

233:9

1213

2222

3

1:22:

43:10

對於這個題,關鍵是要處理乙個數是可拿還是不可拿,由於剛開始輸入的數是無序的,所以我們不好判斷相鄰兩個數的關係。所以我們先對輸入的數進行排序,然後將所有相同的數加到一起,然後進行遍歷。對每乙個值的和,我們首先判斷它是否等於它左邊的數加1,如果等於,就要判斷這個數取還是不取,即比較其左邊的數的和與其左邊兩個和其的和誰大, 從中取出最大的。如果不相等,則直接累加,最後輸出最右邊的數。

#include

#include

using

namespace std;

struct point};

point p[

100010];

int n,all[

100010];

intmain()

}if(flag==0)

cout<.thesum

else

cout<.thesum

}}

動態規劃習題

401最大連續乘積子串 402字串編輯距離 403格仔取數問題 404交替字串 1.子串行個數 子串行的定義 對於乙個序列a a 1 a 2 a n 則非空序列a a p1 a p2 a pm 為a的乙個子串行 其中1 p1 2.數塔取數問題 乙個高度為n的由正整數組成的三角形,從上走到下,求經過的...

動態規劃習題總結

tot是一定的,如果某個值x能夠到達,那麼tot x一定能到達 只用從i tot 2 逐漸減小 開始檢查 是否i和tot i都能到達 動態規劃過程中,只用求出0到tot 2是否能達到即可。hdu 2955 robberies 01揹包,被抓住的概率應該是一連串概率的乘積,因為把概率當作揹包體積不好計...

動態規劃習題整理(1)

狀態表示 f i 表示以第 i 個元素結尾的所有連續子陣列的最大值。狀態轉移 f i max f i 1 0 nums i f i 可劃分為兩部分,以第 i 1個元素結尾的所有連續子陣列加上第i個元素,或者只選用第 i 個元素。答案為所有f i 中的最大值。優化 由於f i 在計算時只會用到f i ...