解題思路
**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/所有數都相等,輸出p[0]
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 ...