62.不同路径(动态规划及优化)
https://blog.csdn.net/xushiyu1996818/article/details/86308900
https://segmentfault.com/a/1190000016315625
思路:
dp存储路径数
初始值是第一行和第一列
递推:dp[i][j] = dp[i-1][j]+dp[i][j-1]
动态规划代码:
class Solution {
public:
int uniquePaths(int m, int n) {
int dp[m][n];
for(int i=0;i<m;i++){
dp[i][0] = 1;
}
for(int j=0;j<n;j++){
dp[0][j] = 1;
}
for(int j=1;j<n;j++){
for(int i=1;i<m;i++){
dp[i][j] = dp[i-1][j]+dp[i][j-1];
}
}
return dp[m-1][n-1];
}
};
64.最小路径和
思路:dp存储当前路径和值
初始值:第一行和第一列的路径和值
递推公式:dp[x][y] = min{dp[x-1][y],dp[x][y-1]}+grid[x][y]
代码:
class Solution {
public:
int minPathSum(vector<vector<int>>& grid) {
int m = grid.size();
int n = grid[0].size();
int dp[m][n];
dp[0][0] = grid[0][0];
for(int i=1;i<n;i++){
dp[0][i] = dp[0][i-1]+grid[0][i];
}
for(int j=1;j<m;j++){
dp[j][0] = dp[j-1][0] + grid[j][0];
}
for(int j=1;j<m;j++){
for(int i=1;i<n;i++){
dp[j][i] = dp[j-1][i]>dp[j][i-1]?(dp[j][i-1]+grid[j][i]):(dp[j-1][i]+grid[j][i]);
}
}
return dp[m-1][n-1];
}
};
放苹果
把M个同样的苹果放在N个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?(注:5,1,1和1,5,1 是同一种分法)
https://blog.csdn.net/qq_27474589/article/details/77949714
思路:
设 f(m,n) 为m个相同的苹果放到n个相同的盘子中的方法总数。下面对n进行讨论,
当 n>m 时,则必有n-m个盘子是空的。去掉这些空盘子对总的摆放情况数目不影响。即当n>m时,有 f(m,n) = f(m,m)
当 n<=m 时,所有的情况可以分成两大类,一类是有空盘的情况,一类是无空盘的情况。
1、有空盘,至少有一个空盘,这类情况数目 f(m,n-1)
2、无空盘,即所有的盘子都装有苹果。从每个盘子中取出一个苹果,对该类情况结果无影响。比如在每个盘子必须有苹果的前提下,4个苹果放到3个盘子中有三种方法;将每个盘子中去掉一个苹果,即1个苹果放到3个盘子中且允许有空盘子,也是三种情况。此类情况总数目 f(m-n,n)
综上当 n<=m时,f(m,n) = f(m,n-1) + f(m-n,n)
递归结束条件:当n=1时返回1;当m=0时返回1;
代码:
#include <iostream>
using namespace std;
int fun(int n,int m){
if(n<m){
return fun(n,n);
}
if(m==0){
return 1;
}
if(n==1){
return 1;
}
return fun(n,m-1)+fun(n-m,m);
}
int main()
{
int n=7,m=3;
int sum = fun(n,m);
cout<<sum;
return 0;
}