您现在的位置是:首页 >技术杂谈 >动态规划——力扣刷题总结网站首页技术杂谈
动态规划——力扣刷题总结
70,爬楼梯
假设你正在爬楼梯。需要 n 阶你才能到达楼顶。
每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢?
简单题:设第n阶的方法为
f
(
x
)
f(x)
f(x),则有
f
(
x
)
=
f
(
x
−
1
)
+
f
(
x
+
2
)
f(x)=f(x-1)+f(x+2)
f(x)=f(x−1)+f(x+2)
代码;
class Solution {
public:
int fn[46];
int climbStairs(int n) {
fn[1]=1;
fn[2]=2;
for(int i=3;i<=n;i++)
{
fn[i]=fn[i-1]+fn[i-2];
}
return fn[n];
}
};
53,最大数组和
设置一个前缀和sum,当sum+x小于x时,即连续数组包括此x值时,不满足题意,将前缀和重新从x开始。
取sum的最大值
代码:
class Solution {
public:
int maxSubArray(vector<int>& nums ) {
int n=nums.size();
int sum=0;
int ans=-999999999;
for(int i=0;i<n;i++)
{
sum=max(sum+nums[i],nums[i]);
ans=max(ans,sum);
}
return ans;
}
};
1706 球会落到何处
对每一层情况进行分析,当前层的位置是有上一层的挡板情况确定,分析清楚什么时候右移一个位置,什么时候左移,什么时候卡在挡板处即可
代码:
class Solution {
public:
vector<int> findBall(vector<vector<int>>& grid) {
int col=grid[0].size();
int row=grid.size();
vector<int>ans(col,0);
for(int i=0;i<col;i++)
{
ans[i]=i;
}
for(int i=0;i<row;i++)
for(int j=0;j<col;j++)
{
if(ans[j]==-1)
continue;
else if(grid[i][ans[j]]==1&&ans[j]+1<col&&grid[i][ans[j]+1]!=-1)
{
ans[j]++;
}
else if(grid[i][ans[j]]==-1&&ans[j]-1>=0&&grid[i][ans[j]-1]!=1)
{
ans[j]--;
}
else{
ans[j]=-1;
}
}
return ans;
}
};
1420 生成数组
设方法数为
f
(
n
,
s
,
j
)
s
f(n,s,j)s
f(n,s,j)s表示search_cost,n表示第几个数,j表示取何值。
f
(
n
,
s
,
j
)
=
f
(
n
−
1
,
s
,
j
)
∗
j
+
∑
i
=
1
x
f
(
n
−
1
,
s
−
1
,
s
(
s
<
j
)
)
f(n,s,j)=f(n-1,s,j)*j+sum_{i=1}^{x}f(n-1,s-1,s(s<j))
f(n,s,j)=f(n−1,s,j)∗j+i=1∑xf(n−1,s−1,s(s<j))
代码:
class Solution {
private:
int mod=1000000007;
int f[51][51][1000];
int ans=0;
public:
int numOfArrays(int n, int m, int k) {
for(int i=1;i<=m;i++)
{
f[1][1][i]=1;
}
for(int i=2;i<=n;i++)
for(int s=1;s<=k&&s<=i;s++)
for(int j=1;j<=m;j++)
{
f[i][s][j]=(long long)f[i-1][s][j]*j%mod;
for(int temp=1;temp<j;temp++)
{
f[i][s][j]+=f[i-1][s-1][temp];
f[i][s][j]%=mod;
}
}
for(int j=1;j<=m;j++)
{
ans+=f[n][k][j];
ans%=mod;
}
return ans%mod;
}
};