动态规划练习
Posted 楠c
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了动态规划练习相关的知识,希望对你有一定的参考价值。
乘积最大子数组
普通解法
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n=nums.size();
vector<int> maxdp(n,0);
vector<int> mindp(n,0);
maxdp[0]=nums[0];
maxdp[0]=nums[0];
for(int i=1;i<n;i++)
{
int nums1=nums[i]*maxdp[i-1];
int nums2=nums[i]*mindp[i-1];
maxdp[i]=max(nums[i],max(nums1,nums2));
mindp[i]=min(nums[i],min(nums1,nums2));
}
int maxN=nums[0];
for(auto& e:maxdp)
{
maxN=max(maxN,e);
}
return maxN;
}
};
优化空间
class Solution {
public:
int maxProduct(vector<int>& nums) {
int n=nums.size();
int maxN=nums[0];
int minN=nums[0];
int result=maxN;
for(int i=1;i<n;i++)
{
int nums1=nums[i]*maxN;
int nums2=nums[i]*minN;
maxN=max(nums[i],max(nums1,nums2));
minN=min(nums[i],min(nums1,nums2));
result=maxN>result?maxN:result;
}
return result;
}
};
整数拆分
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1,0);
dp[2]=1;
for(int i=2;i<=n;++i)
{
//dp[i]可以由(i-j)*j,或者dp[i-j]*j推导而来,取最大的一个
//而再循环过程中dp[i]随时可能变化,则需要取更大
//所以是两层max
for(int j=1;j<i;++j)
{
dp[i]=max(dp[i],max((i-j)*j,dp[i-j]*j));
}
}
return dp[n];
}
};
买卖股票的最佳时机
class Solution {
public:
int maxProfit(vector<int>& prices) {
int n=prices.size();
vector<int> dp(n,0);
int minPrices=prices[0];
//dp[0]=0,前0天最大利润为0
for(int i=1;i<n;i++)
{
//保存最小的价格
minPrices=minPrices<prices[i]?minPrices:prices[i];
//上一次最大利润,本次最大利润,取大的那一个
dp[i]=max(dp[i-1],prices[i]-minPrices);
}
return dp[n-1];
}
};
机器人的运动范围
根据题意:sum=i/10+i%10+j/10+j%10;
class Solution {
public:
int movingCount(int m, int n, int k) {
vector<vector<bool>> vv(m,vector<bool>(n,false));
vv[0][0]=true;
//[0,0]算一个
int count=1;
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
int sum=i/10+i%10+j/10+j%10;
//从上面或左边来都可以。
//i为0,就判断能不能从左边来。j为0就判断能不能从上面来
//其余情况只要能从一边来就说明可以来,同时他们整体还要 && sum<=k
if( ((i>0 && vv[i-1][j]) || (j>0 && vv[i][j-1]))&& sum<=k)
{
vv[i][j]=true;
count++;
}
}
}
return count;
}
};
以上是关于动态规划练习的主要内容,如果未能解决你的问题,请参考以下文章