一.dp
1.1核心:dp转移方程
1.2数据结构:int dp[][]
1.3步骤:
dp数组初始化、dp转移方程、dp[n-1][n-1]
1.4优化
空间优化(二维->一维)
1.5 example
①斐波那契数列
递归解法:
int fib(int n){
if(n==1 || n==2) return 1;
return (fib(n-1)+fib(n-2));
}
dp解法:
int fib(int n){
int dp[100];
dp[0]=1;
dp[1]=1;
for(int i=2;i<=n;i++)
dp[i]=dp[i-1]+dp[i-2];
return dp[n];
}
②01背包
0.dp[i][j]:当前可以选择的背包有i个,有j元钱,可以得到的最大化效益是多少
1.初始化 dp[0][i]=j>c[0]?w[0]:0;
2.状态转移方程:
if(j>=c[i]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-c[i]]+w[i]);
else dp[i][j]=dp[i-1][j];
3.ans:ans=dp[n-1][n-1]
4.优化:一维数组,i:n->c[i]
③最长公共子序列
1.dp[i][j]:Xi和Yj的最长公共子序列
2.状态转换方程:if(xi==yi) dp[i][j]=dp[i-1][j-1]+1; else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
3.ans:dp[n-1][m-1]
④最长递增子序列
1.dp[i]:以数组下标为i的值为子序列最后一个元素的序列中,最长自增子序列的长度
2.状态转换方程:dp[i]=-1; for j in (0,i) if(num[i]>num[j]) dp[i]=max{dp[i],dp[j]}; dp[i]++;
1.6特性
子问题的重叠性、求解的是最优子结构、可以与递归相互转化,但是递归效率低、