70. 爬楼梯 (进阶)
解题方法
1.dp数组及下标含义:
dp[i]:爬i阶楼梯有dp[i]种方法
2.递推公式:
dp[i]+=dp[i-j]
3.初始化
dp[0]=1;
dp[i]=0;i非0
4.确定遍历顺序
外层背包,内层物品
5.打印dp数组
Code
#include<iostream>
#include<vector>
using namespace std;
int main()
{
int n,m;
while(cin>>n>>m)
{
vector<int>dp(n+1,0);
dp[0]=1;
for(int i=1;i<=n;i++)//背包
{
for(int j=1;j<=m;j++)
{
if((i-j)>=0){
dp[i]+=dp[i-j];
}
}
}
cout<<dp[n]<<endl;
}
}
复杂度
时间复杂度
O(n*m),m:最多爬m个台阶,n总共有n阶台阶
空间复杂度
O(n)
322. 零钱兑换
解题方法
1.dp数组及下标含义
dp[i]:凑成总金额amount的最少的硬币个数
2.确定递推公式:
dp[i]=min(dp[i-coins[j]]+1,dp[i])
3.初始化:
dp[0]=0;
dp[i]=最大值,避免被覆盖,i非0
4.确定遍历顺序
外层背包,内层物品(该题内外层可以颠倒)
5.打印dp数组
Code
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
vector<int>dp(amount+1,INT_MAX);
dp[0]=0;
for(int i=1;i<=amount;i++)
{
for(int j=0;j<coins.size();j++)
{
if(i-coins[j]>=0&&dp[i-coins[j]]!=INT_MAX){
dp[i]=min(dp[i-coins[j]]+1,dp[i]);
}
}
}
if(dp[amount]==INT_MAX)return -1;
return dp[amount];
}
};
复杂度
时间复杂度:
O(m*n),m:coins的长度,n:amount
空间复杂度:
O(n)
279.完全平方数
解题方法
1.dp数组及下标含义:
dp[j]:和为J的完全平方最少数量为dp[j]
2.确定递推公式:
dp[j]=min(dp[j-i*i]+1,dp[j])
3.初始化:
dp[0]=0;dp[j]=最大值,避免被覆盖
4.确定遍历顺序:
外层为n,内层为完全平方数
5.打印dp数组
Code
class Solution {
public:
int numSquares(int n) {
vector<int>dp(n+1,INT_MAX);
dp[0]=0;
for(int i=0;i<=n;i++)
{
for(int j=1;j*j<=i;j++)
{
dp[i]=min(dp[i-j*j]+1,dp[i]);
}
}
return dp[n];
}
};
复杂度
时间复杂度:
O(√n*n)
空间复杂度:
O(n)