额,与爬楼梯类似,路径总数目 dp[m][n] = dp[m-1][n]+dp[m][n-1]。得考虑边界问题,当为1,2,3的时候
static int result[101][101] = {0};
class Solution {
public:
int uniquePaths(int m, int n) {
if(m<=0||n<=0) return 0;
else if (m==1||n==1) return 1;
else if (m==2&&n==2) return 2;
else if ((m==3&&n==2)||(m==2&&n==3)) return 3;
if (result[m][n]>0) return result[m][n];
result[m][n-1] = uniquePaths(m,n-1);
result[m-1][n] = uniquePaths(m-1,n);
result[m][n] = result[m-1][n] + result[m][n-1];
return result[m][n];
}
};
1,动态规划求解,dp[i]代表i分割后得到的乘积最大的元素,比较类似最长上升子序列,每次需要和之间所有的状态进行比较。
转移方程为:dp[i] = max(dp[i],(i-j)*max(dp[j],j))(i>j), 因为dp[j]没有包括当前分割当前元素乘机最大的情况。
2,还有数学优化证明,第二遍再说吧
class Solution {
public:
int integerBreak(int n) {
vector<int> dp(n+1,0);
dp[1] = 1;
for(int i=2;i<=n;i++){
for(int j=0;j<i;j++){
dp[i] = max(dp[i],(i-j)*max(dp[j],j));
}
}
return dp[n];
}
};
1,动态规划求解,一个元素对应多个对应的子状态组成,类似于之前比较的状态转移方程,这儿转换为了多次比较,动态转移方程如下:dp[i+j*j] = min(dp[i+j*j],dp[i]+1)(这道题不是特别懂)
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;i+j*j<=n;j++){
dp[i+j*j] = min(dp[i+j*j],dp[i]+1);
}
}
return dp[n];
}
};
2,还有一种动态规划,我觉得挺好的,定义一个函数f(n),表示我们要求的解,f(n)的求解为f(n) = 1+min(f(n-1^2)+...+f(n-k^2),k^2<=n)
class Solution {
public:
int numSquares(int n) {
vector<int> f(n+1,0);
for(int i = 1;i<=n;i++){
int minVal = INT_MAX;
for(int j = 1; j*j<=i;j++){
minVal = min(minVal,f[i-j*j]);
}
f[i] = minVal+1;
}
return f[n];
}
};
1,O(nlog2n),把这个看作维护一个最长子序列的数组的任务,如果满足递增的时候就压入,且长度
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
if(nums.size()==0)
{
return 0;
}
int len=0;
int dp[nums.size()];
dp[0]=nums[0];
for(int i=1;i<nums.size();i++)
{
if(nums[i]>dp[len])
{
dp[++len]=nums[i];
}
else
{
int j=lower_bound(dp,dp+len,nums[i])-dp;
dp[j]=nums[i];
}
}
return len+1;
}
};
2,动态规划,设f(i)为第i位最长递增子序列长度 f[i] = max(f[i],f[j]+1);
class Solution {
public:
int lengthOfLIS(vector<int>& nums) {
int len = nums.size();
int result = -INT_MAX;
if (len ==0) return 0;
vector<int> dp(len,1);
dp[0] = 1;
for(int i=0;i<=len-1;i++){
for(int j=0;j<i;j++){
if(nums[j]<nums[i])
dp[i] = max(dp[i],dp[j]+1);
}
result = max(result,dp[i]);
}
return result;
}
};
不跑步就刷题