遞迴與動態規劃之六

2021-09-01 12:24:49 字數 4141 閱讀 7878

數字字串轉換為字母組合的種數

表示式得到期望結果的組成種數

排成一條線的紙牌博弈問題

跳躍遊戲

陣列中的最長連續序列

給定乙個二維陣列map,含義是一張地圖。遊戲規則如下:

1、騎士從左上角出發,每次只能向右或向下走,最後到達右下角見到公主。

2、地圖中每個位置的值表示騎士的遭遇。如果是負數,此處有怪獸,要讓騎士損失血量。如果是非負數,代表此處有血瓶,可以讓騎士回血。

3、騎士從左上角到右下角的過程中,走到任何乙個位置時,血量都不能少於1.

為了保證能見到公主,初始血量至少是多少?根據map,返回初始血量。

#include

#include

#include

using

namespace std;

intminhp1

(vectorint>> mp)

int right =0;

int down =0;

for(

int i = row -

2; i >=

0; i--)}

return dp[0]

[0];

}//空間壓縮

intminhp2

(vectorint>> mp)

int choosen1 =0;

int choosen2 =0;

for(

int i = more -

2; i >=

0; i--)}

return dp[0]

;}intmain()

}int res1 =

minhp1

(in)

;int res2 =

minhp2

(in)

; cout << res1 <<

" "<< res2 << endl;

getchar()

;return0;

}

給定乙個字串str,str全部由數字字元組成,如果str中某乙個或某相鄰兩個字元組成的子串值在1~26之間,則這個子串可以轉換成乙個字母。規定『1』轉換為『a』,『2』轉換為『b』,…,『26』轉換成『z』。實現乙個函式,求str有多少種不同的轉換結果,並返回種數。

#include

#include

#include

using

namespace std;

//遞迴

intprocess

(string str,

int i)

intnum1

(string str)

intnum2

(string str)

else

}return cur;

}int

main()

給定乙個只由0(假)、1(真)、&(邏輯與)、|(邏輯或)和^(異或)五種字元組成的字串express。再給定乙個布林值desired。返回express能有多少種組合方式,可以達到desired的成果。

#include

#include

#include

#include

using

namespace std;

/*首先判斷表示式是否有效,以下幾個標準:1、表示式長度必須為奇數

2、表示式下標為偶數的位置的字元一定是『0』或『1』

3、表示式下標為奇數字置的字元一定是『&』或『|』或'^'*/

bool

isvalid

(string str)

for(

int i =

1; i < len; i +=2

)return

true;}

/*如果為真之後,遞迴判斷有多少種劃分方式,累加給定結果的不同劃分方式

得到最後結果*/

intp

(string str,

bool desired,

int l,

int r)

int res =0;

if(desired)}}

else}}

return res;

}int

num1

(string str,

bool desired)

intnum2

(string str,

bool desired)

else

if(str[k +1]

=='|'

)else}}

}return desired ? t[0]

[len -1]

: f[0]

[len -1]

;}intmain()

給定乙個整形陣列arr,代表數值不同的紙牌排成一條線。玩家a和玩家b依次拿走每張紙牌,規定玩家a先拿,玩家b後拿,但是每個玩家每次只能拿走最左或最右的紙牌,玩家a和玩家b都絕頂聰明。請返回最後獲勝者的分數。

#include

#include

#include

using

namespace std;

ints

(int arr,

int i,

int j)

;intf(

int arr,

int i,

int j)

;ints(

int arr,

int i,

int j)

intf

(int arr,

int i,

int j)

intwin1

(int arr,

int len)

/*遞迴的方法導致時間複雜度達到o(2^n),空間複雜度為o(n);

動態規劃生成兩個矩陣f,s,f[i][j]表示函式f(i, j)的返回值,s[i][j]表示

函式是是s(i, j)的返回值*/

intwin2

(int arr,

int len)

}return

max(f[0]

[len -1]

, s[0]

[len -1]

);}int

main()

int res1 =

win1

(in, n)

;int res2 =

win2

(in, n)

; cout << res1 <<

" "<< res2 << endl;

getchar()

;return0;

}

給定陣列arr,arr[i]==k代表可從位置i向右跳1-k個距離。比如arr[2]==3,代表從位置2可以跳到位置3或4或5.如果從位置0出發,返回最少跳幾次能跳到arr最後的位置上。

要求:如果arr長度為n,要求實現時間複雜度為o(n),額外空間複雜度為*o(1)*的方法。

int

jumpgame

(int arr,

int len)

next =

max(next, i + arr[i]);

}return step;

}

給定無序陣列arr,返回其中最長的連續序列的長度。

使用雜湊表可以實現時間複雜度為o(n)、額外空間複雜度為o(n)的方法。

#include

#include

#include

#include

using

namespace std;

intmerge

(map<

int,

int>

&mp,

int less,

int more)

intmaxconsecutive

(int arr,

int len)

if(m.

find

(arr[i]+1

)!= m.

end())

}}return maxlen;

}int

main()

動態規劃與遞迴

這裡借用leetcode的一道例題,來說一下動態規劃和遞迴的區別 給定乙個三角形,找出自頂向下的最小路徑和。每一步只能移動到下一行中相鄰的結點上。相鄰的結點 在這裡指的是 下標 與 上一層結點下標 相同或者等於 上一層結點下標 1 的兩個結點。例如,給定三角形 2 3,4 6,5,7 4,1,8,3...

動態規劃訓練之六

這是一道好題 題目描述 求1 n排列組成的波動數列的個數 分析首先肯定是個dp沒錯了,考慮設計方案,dp i,j 表示用1 i的排列最後乙個為j的方案數 dp i,j 相當於dp i 1,k 中原排列大於等於j的數都加1,再把j插到末尾後的新合法排列的方案數 類似test10.7的排列題 答案有 m...

js動態規劃與遞迴

動態規劃 從底部開始解決問題,將所有 小問題解決掉,然後合併成乙個整體解決方案,從而解決掉整個大問題 遞迴 從頂部開始將問題分解,通過解決掉所有分解的小問題來解決整個問題 計算斐波那契數列 function recurfib n else 遞迴 很多函式執行了多次 動態規劃使用乙個陣列儲存部分函式計...