b - lis & lcs
c-拿數問題 ii
a-簽到題
題目要求
東東在玩遊戲「game23」。
在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出-1。
input
輸入的唯一一行包括兩個整數n和m(1<=n<=m<=5*10^8).
output
輸出從n轉換到m的操作次數,否則輸出-1.
求解思路
採用遞迴的方式進行乘2,乘3排列,遞迴終止條件為找到m,或者大於m。
通過p記錄操作的次數,jud記錄是否找到m。
最優解性質:void
func
(int num,
int p)
if(num == m)
func
(num *
2,p+1)
;func
(num *
3,p+1)
;}
n 轉成 m
動態規劃方程
自底向上(遞推)或帶備忘的自頂向下(記憶化搜尋)方式計算最優值
構造最優解
**
b - lis & lcs#include
#include
#include
using
namespace std;
int n, m;
bool jud;
int k;
void
func
(int num,
int p)
if(num == m)
func
(num *
2,p+1)
;func
(num *
3,p+1)
;}intmain()
else
}
題目要求
lis:最長遞增序列
lcs:最長公有序列
東東有兩個序列a和b。
他想要知道序列a的lis和序列ab的lcs的長度。
注意,lis為嚴格遞增的,即a1****** input
5 51 3 2 5 4
2 4 3 1 5
****** output
3 2求解思路
lis:
最優解性質:
最長上公升子串行
動態規劃方程
初始化 f1=1
轉移方程 fi = max + 1
自底向上(遞推)或帶備忘的自頂向下(記憶化搜尋)方式計算最優值
採用遞推方式:
通過兩重迴圈更新f陣列的值:
當 j < i && aj < ai 時,ai可以至少為aj + 1,掃瞄a2~ai,滿足 j < i && aj < ai 最大的aj + 1 即為 ai 的值。
構造最優解for
(int i=
2;i<=n;i++
)for
(int j =
1; j < i; j++)}
}
最優解為 max
時間複雜度 o(n^2)ll mx =0;
for(
int i =
1; i <= n; i++)}
return mx;
lcs:
最優解性質:
最長公共子串行
動態規劃方程
初始化 f[1][0]= f[0][1]= f[0][0]=0
轉移方程
當 ai==bj時,f[i][j] = f[i-1][j-1]+ 1,否則,f[i][j] = max
自底向上(遞推)或帶備忘的自頂向下(記憶化搜尋)方式計算最優值
採用遞推方式:
通過兩重迴圈更新f陣列的值:
構造最優解for
(int i=
1;i<=n;i++
)for
(int j =
1; j <= m; j++
)else
}
最優解為 f[n][m]
時間複雜度 o(nm)
**
c-拿數問題 ii#include
#include
#include
typedef
long
long ll;
using
namespace std;
ll a[
5005];
ll b[
5005];
ll f[
5005];
ll g[
5005][
5005];
ll n, m;
ll lis()
for(
int i=
2;i<=n;i++
)for
(int j =
1; j < i; j++)}
} ll mx =0;
for(
int i =
1; i <= n; i++)}
return mx;
}ll lcs()
else
}return g[n]
[m];
}int
main()
for(
int i =
1; i <= m; i++
) cout <<
lis(
)<<
" "<<
lcs();
}
題目要求
yjq 上完第10周的程式設計思維與實踐後,想到乙個絕妙的主意,他對拿數問題做了一點小修改,使得這道題變成了 拿數問題 ii。
給乙個序列,裡邊有 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你能得到最大分值。
example
input
21 2
output
2input
31 2 3
output
4input
91 2 1 3 2 2 2 2 3
output
10hint
對於第三個樣例:先選任何乙個值為2的元素,最後陣列內剩下4個2。然後4次選擇2,最終得到10分。
求解思路
最優解性質:
能得到的最大分值
動態規劃方程
按照分值
初始化:dp[0] = 0; dp[1] = arr[1];
轉移方程 :dp[i] = max(dp[i - 1], dp[i - 2] + arr[i]*i);
其中arr[i]為大小為i的數的個數,dp[i]為小於i的數可取到的最大分值。
自底向上(遞推)或帶備忘的自頂向下(記憶化搜尋)方式計算最優值
採用遞推方式:
通過一重迴圈更新dp陣列的值
構造最優解
設給出的數字最大值為max
最優解為 dp[max],因為1 ≤ ai ≤ 10^5,所以可以直接取dp[100003]
時間複雜度 o(n)
**
#include
#include
#include
typedef
long
long ll;
using
namespace std;
ll arr[
100005];
ll dp[
100005];
intmain()
for(ll i =
0; i < n; i++
) dp[0]
=0; dp[1]
= arr[1]
;for
(ll i =
2; i <
100005
; i++
) cout << dp[
100003];
}
week10 作業 動態規劃(一)
東東在玩遊戲 game23 在一開始他有乙個數字n,他的目標是把它轉換成m,在每一步操作中,他可以將n乘以2或乘以3,他可以進行任意次操作。輸出將n轉換成m的操作次數,如果轉換不了輸出 1。輸入的唯一一行包括兩個整數n和m 1 n m 5 10 8 輸出從n轉換到m的操作次數,否則輸出 1.120 ...
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...