动态规划三大步骤
- 定义数组元素含义。一般用dp[],明确dp[i]含义。
- 找出数组元素的关系式。比如斐波那契数列,dp[i]=dp[i-1]+dp[i-2]。
- 找出初始值。比如斐波那契数列dp[0]、dp[1]不能再分解,dp[0]=0,dp[1]=1。
思路:建议背诵
public int fib(int n) {
if(n==0)
return 0;
if(n==1)
return 1;
int[] dp = new int[n+1];
dp[0] = 0;
dp[1] = 1;
for (int i=2;i<=n;i++){
dp[i] = dp[i-1]+dp[i-2];
}
return dp[n];
}
剑指 Offer 10- II. 青蛙跳台阶问题
思路:和斐波那契数列相似,就是初始条件变多。
public int numWays(int n) {
if (n==0)
return 1;
if (n==1)
return 1;
if (n==2)
return 2;
int[] dp = new int[n+1];
dp[0]=0;
dp[1]=1;
dp[2]=2;
for (int i=3;i<=n;i++){
dp[i] = (dp[i-1]+dp[i-2])%1000000007;
}
return dp[n];
}
剑指 Offer 63. 股票的最大利润
思路:没有用到dp[]。用min记录当前最低价;res记录最佳利润。prices[i]<min更新min,否则更新利润。(中等难度)
public int maxProfit(int[] prices) {
if (prices==null || prices.length==0)
return 0;
int min = prices[0];
int res = 0;
int[] dp = new int[prices.length];
for (int i=1;i<prices.length;i++){
if (prices[i]<min){
min = prices[i];
}else {
res = Math.max(res,prices[i]-min);
}
}
return res;
}