数塔问题:
思路:dp数组记录底层,然后每次上一层加上下一层两边的最大值就行了
转移方程:dp [ i ] [ j ] = max(dp[i+1][j] ,dp[i+1][j+1]) + f[i][j]
i 是倒序的,从n-1 到 1吧,然后每次j会<=i,回到1
1 | //数塔问题:可以从第一层加至第五层,每次选一层一个数; |
最大连续子列和
思路:每次寻找最大添加该元素后的连续子序列,和当前序列本身
转移方程:dp[i] = max(a[i],dp[i-1]+a[i])
1 | //最大连续子列和问题 |
连续不下降最长子序列LIS:
思路:每次让dp[i]的长度为1,然后判断a[i]是否大于a[j],dp[j]+1是否大于dp[i]如果满足则进行转移,i表示以i结尾的子序列,所以j<i
转移方程:if a[i]>a[j] && dp[j]+1>dp[i] 则进行转移 dp[i]=dp[j+1]
1 | //最长连续不下降子序列 |
最长公共子序列问题LCS:
思路:i表示s1串的前i个字母,j表示s2串的前j个字母,进行判断是有两种可能一种是 s1[i] == s2[j],则dp[i+1][j+1]=dp[i][j]+1, 另一种是s1[i] != s2[j] 的情况,这种情况就是判断 dp[i+1][j] 和dp[i][j+1] 的大小,等于之间较大的这样转移方程就出来了。
1 | //最长公共子序列问题 |
背包问题大合集:
01 背包
注意for的顺序
for i = 0:n-1
for j = W:w[i]
状态转移方程 dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
完全背包问题
for i = 0:n-1
for j = w[i]:W
状态转移方程 dp[j] = max(dp[j],dp[j-w[i]]+v[i]);
1 |
|