把握要點:動態規劃問題要注意儲存子問題的值,並且在過程中,不要忘記使用它
經典面試題10
題目描述:和第九題的框架相同,機械人還是要從網格左上角到達右下角,
但是網格中新增了障礙物,障礙物用1表示
狀態定義:
子狀態從(0,0),(0,1),(1,0)…(m-1,n-1)的路徑數
f(i,j):從f(0,0)到f(i,j)的路徑數**狀態轉移方程的定義:
當這個點為0:f(i,j)=f(i,j-1)+f(i-1,j)
當這個點位1:0 **
狀態的初始化:f(i,0)=f(o,j)=返回結果:f(m-1,n-1)
注意:如果此點為障礙物,則後面點都到達不了
public
class
solution
int m=obstacles.length;
int n=obstacles[0]
.length;
//用來儲存每乙個點的路徑值
int[
] temp=
newint
[m][n]
;//初始化,第一行,第一列的值若不為1(障礙),則到達的路徑數為1
for(
int i=
0;i)else
}for
(int j=
0;j)else
}for
(int i=
1;i)else}}
return temp[m-1]
[n-1];
}}
經典面試題11
題目描述:題目描述:
給定乙個m*n的網格,網格用非負數填充,找到一條從左上角到右下角的最短路徑。
注:每次只能向下或者向右移動。
狀態定義:
子狀態從(0,0),(0,1),(1,0)…(m-1,n-1)的路徑數
f(i,j):從f(0,0)到f(i,j)的路徑數狀態轉移方程的定義:
f(i,j)=min(f(i-1)(j),f(i)(j-1))+a[j]狀態的初始化:f(0,0)=a(0,0)
第一行:f(i,0)=f(i-1,0)+a[i][0]
第一列:f(0,j)=f(0,j-1)+a[0][j]返回結果:f(m-1,n-1)
public
class
solution
int m=grid.length;
int n=grid[0]
.length;
int[
]temp=
newint
[m][n]
;//初始化
temp[0]
[0]=grid[0]
[0];
for(
int i=
1;i)for
(int j=
1;j)for
(int i=
1;ireturn temp[m-1]
[n-1];
}}
經典面試題12
題目描述:題目描述:
有 n 個物品和乙個大小為 m 的揹包. 給定陣列 a 表示每個物品的大小和陣列 v 表示每個物品的價值.
問最多能裝入揹包的總價值是多大?
狀態定義:
f(i, j): 前i個物品放入大小為j的揹包中所獲得的最大價值狀態轉移方程的定義:
對於第i個商品:
如果裝不下:此時的價值與前i-1個的價值是一樣的f(i,j) = f(i-1,j)
如果可以裝下:需要在兩種選擇中找最大的
f(i, j) = max
f(i-1,j): 表示不把第i個物品放入揹包中, 所以它的價值就是前i-1個物品放入大小為j的揹包的最大價值
f(i-1, j - a[i]) + v[i]:表示把第i個物品放入揹包中,價值增加v[i],但是需要騰出a[i]的大小放第i個商品狀態的初始化:f(0,0)=a(0,0)
第0行和第0列都為0,(沒有物品,沒有容量)因此表示物品的價值都為0
f(0,j) = f(i,0) = 0返回結果:f(n,m)
public
class
solution
//多開闢一行一列用於儲存初始值,a的大小,m的大小都代表真實的值
int n=a.length+1;
int m=m+1;
//儲存揹包的價值
int[
] result=
newint
[n][m]
;//第0行(表示沒有物品),第0列(表示沒有揹包容量),因此價值都為0,
for(
int i=
0;i)for
(int j=
0;j)for
(int i=
1;i)else}}
//返回裝入前n個商品,物品大小為m的最大價值
return result[n-1]
[m];
}}
經典面試題13
題目描述:題目描述:
給定乙個字串 s,把 s 分割成一系列的子串,分割的每乙個子串都為回文串
返回最小的分割次數
比如,給定 s = 「aab」,
返回1,因為一次cut就可以產生回文分割[「aa」,「b」]
狀態定義:
f(i): 前i個字串的最小分割次數狀態轉移方程的定義:
f(i) = min(f(i), 1 + f(j) (jj, j+1–>i都為回文串。狀態的初始化:f(i)=i-1;(『a』)不需要切割返回結果:f(n)
public
class
solution
int length=s.
length()
;//用於儲存到每個字母的最小分割次數
int[
] result=
newint
[length+1]
;//初始化,注意邊界,0代表0個元素,
for(
int i=
0;i1;i++
)for
(int i=
1;i1;i++),
//從最長串判斷,如果從第j+1到i為回文字串
//則再加一次分割,從1到j,j+1到i的字元就全部分成了回文字串if(
ispalindrome
(s, j, i -1)
)}}return result[length];}
private
boolean
ispalindrome
(string s,
int j,
int i)
j++; i--;}
return
true;}
}
動態規劃2
動態規劃是研究一類最優化問題的方法,在經濟 工程技術 企業管理 工農業生產及軍事等領域中都有廣泛的應用。近年來,在acm icpc中,使用動態規劃 或部分應用動態規劃思維 求解的題不僅常見,而且形式也多種多樣。而在與此相近的各類資訊學競賽中,應用動態規劃解題已經成為一種趨勢,這和動態規劃的優勢不無關...
動態規劃(2)
題目輸入格式 第1行 兩個數字r,c 1 r,c 100 表示矩陣的行列。第2.r 1行 每行c個數,表示這個矩陣。輸出格式 僅一行 輸出1個整數,表示可以滑行的最大長度。樣例輸入 5 5 1 2 3 4 5 16 17 18 19 6 15 24 25 20 7 14 23 22 21 8 13 ...
動態規劃2
最長遞增子串行的問題 給定陣列arr,返回arr的最長遞增子串行長度。比如arr 最長遞增子串行為,返回arr的最長遞增子串行長度。比如arr 最長遞增子串行為所以返回這個子串行的長度為5。解決方案 arr 2 1 5 3 6 4 8 9 7 dp 1 1 2 2 3 3 4 5 4 dp i 表示...