Acy夕拾算法 Week2_day5
LeetCode 322. 零钱兑换
/*
·X贪心X:先取最大的,如果>了再往小取;不行,eg:[1,4,5] 12 ⑤2+①2=4;④*3=3
·dp:通过子问题得到最优解,
·并且题目只问:硬币个数,不需要知道用了哪几个
··类爬楼梯:取到达当前位置的最小
··类完全背包:取最少的物品装满背包
1.确定dp数组以及下标的含义:dp[i]:总金额为i时,需要的最少硬币个数
2.确定递推公式:dp[i] = min( dp[i], dp[i-coins[小于i的]]+1 )
3.dp数组如何初始化:dp[0]=0;取min所以初始化用INT_MAX
4.确定遍历顺序:顺序
*/
class Solution {
public:
int coinChange(vector<int>& coins, int amount) {
// if(amount == 0) return 0;
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(coins[j] <= i && dp[i-coins[j]] != INT_MAX)
dp[i] = min( dp[i], dp[i-coins[j]]+1 );
}
}
return dp[amount]>amount ? -1 : dp[amount];//最小硬币为1,比全为1个数还多,其实是没找到
}
};
LeetCode 300. 最长递增子序列
/*
删掉重复的、影响增的0,1,2,3;数组不好删除,直接计数
dp取最大的,0-下标 作为一个子问题
1.确定dp数组以及下标的含义:dp[i]:0~i时的最长增序列
2.确定递推公式:dp[i] = max( dp[i], dp[j]+1 )取dp[j] + 1的最大值
3.dp数组如何初始化:dp[0]=1;
4.确定遍历顺序:顺序
*/
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
vector<int> dp(nums.size()+1, 1);
// dp[0] = 1;
// dp[1] = 1;
for(int i = 1; i < nums.size(); i++)
{
for(int j = 0; j < i; j++)
{
if(nums[i] > nums[j])
dp[i] = max(dp[i], dp[j]+1);
}
}
int res = dp[0];
for(int i = 1; i < dp.size(); i++)
res = max(res, dp[i]);
return res;
}
};