week10 作業 動態規劃(一)

2021-10-05 10:37:18 字數 3392 閱讀 4732

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

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

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

120 51840
7
42 42
0
48 72
1
該題要判斷n是否可以通過乘以2或者乘以3的方式得到m,那麼就可以反過來對m進行因式分解,看m是否可以分解成若干個2或者3和n的乘積組合的形式,如果可以那麼輸出因數的個數,否則說明不能得到輸出-1。

#include

#include

using

namespace std;

bool

solve

(int m)

//判斷是不是質數 }if

(i==m&&m!=1)

return

false;}

intmain()

else

while

(m!=

2&&m!=

1&&m!=3)

else

if(m%2==

0)else

} cout<}return0;

}

東東有兩個序列a和b。

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

注意,lis為嚴格遞增的,即a1第一行兩個數n,m(1<=n<=5,000,1<=m<=5,000)。

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

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

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

5 5

1 2 3 4 5

3 2 1 4 5

5 3
關於lis&lcs的詳解以及演算法的優化見動態規劃-各種子串行問題

#include

#include

#include

#include

using

namespace std;

const

int maxn=

5e3+5;

int dp_lis[maxn]

;int dp_lcs[maxn]

[maxn]

;int a[maxn]

,b[maxn]

;int

main()

for(

int i=

1;i<=m;i++

)for

(int i=

1;i<=n;i++

)//初始化 }}

int ans1=0;

for(

int i=

1;i<=n;i++

)//初始化

memset

(dp_lcs,0,

sizeof

(dp_lcs));

for(

int i=

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

} cout<" "<[m]

}

yjq 上完第10周的程式設計思維與實踐後,想到乙個絕妙的主意,他對拿數問題做了一點小修改,使得這道題變成了 拿數問題 ii。

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

本題和課上講的有些許不一樣,但是核心是一樣,需要你自己思考。

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

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

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

2 

1 2

2
3 

1 2 3

4
9 

1 2 1 3 2 2 2 2 3

10
對於第三個樣例:先選任何乙個值為2的元素,最後陣列內剩下4個2。然後4次選擇2,最終得到10分。

該題在原來的拿數問題上進行了修改,關鍵在於理解x+1 和 x-1 (如果有 aj = x+1 或 aj = x-1 存在) 就會變得不可拿(但是有 aj = x 的話可以繼續拿這個 x)這一句話,這句話說明不再是按照位置進行選或者不選,而是按照數的大小進行決策,所以我們的dp[i]陣列針對的不再是數的下標而是數的大小。

(注意資料範圍,數的個數e5,數的大小e5,那麼最大分值可能會超過int取值範圍,所以需要long long int)

#include

#include

#include

using

namespace std;

const

int maxn=

1e5+5;

const

int inf=

1e8+8;

long

long

int dp[maxn]

;long

long

int cnt[maxn]

;long

long

int minn=inf;

long

long

int maxx=0;

intmain()

memset

(cnt,0,

sizeof

(cnt));

for(

int i=

1;i<=n;i++

)//記錄每個數出現個數

for(

int i=minn;i<=maxx;i++

)long

long

int ans=0;

for(

int i=minn;i<=maxx;i++

) cout

}

week10作業 動態規劃(一)

b lis lcs c 拿數問題 ii a 簽到題 題目要求 東東在玩遊戲 game23 在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出 1。input 輸入的唯一一行包括兩個整數n和m 1...

week10 作業(動態規劃1)

問題分析 心得體會 b lis lcs 問題分析 心得體會 c 拿數問題 ii 問題分析 心得體會 題目簡述 東東在玩遊戲 game23 在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出 1。...

week10作業簽到

東東在玩遊戲 game23 在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出 1。輸入的唯一一行包括兩個整數n和m 1 n m 5 10 8 輸出從n轉換到m的操作次數,否則輸出 1.samp...