1.动态规划
此题和上一题的解法基本一样
设dp(len),dp[i]表示以nums[i]结尾的最长子序列的长度
设count(len),count[i]表示以nums[i]结尾的长度为dp[i]的序列个数
对于dp[i]的求法,仍然是dp[i],dp[j]+1中的最大值,不过在这里需要区分情况
对于i>j,当nums[i]>nums[j](j从0---i-1),表示可以将nums[i]添加在nums[j]后面,此时分为两种情况:
1)dp[j]+1>dp[i],说明第一个找到长度为dp[j]+1且以nums[i]结尾的递增子序列,则dp[i]=dp[j]+1.count[i]=count[j](以nums[i]结尾的递增子序列个数等于以nums[j]结尾的递增子序列的个数)
2)dp[j]+1=dp[i],说明不是长度为dp[j]+1(或dp[i])且以nums[i]结尾的递增子序列不是第一次找到,
原有的长度为dp[i]以nums[i]结尾的序列数是count[i],
新找到的长度为dp[i]且以nums[i]结尾的序列个数为count[j],
则总的长度为dp[i]以nums[i]结尾的序列数是count[i]+count[j],即count[i]=count[i]+count[j]
遍历过程中,记录最长子序列的长度,记为imax
然后遍历dp,记录与imax相等的dp[i]对应的count[i]
代码如下:
class Solution {
public:
int findNumberOfLIS(vector<int>& nums) {
int len=nums.size();
vector<int> dp(len,1);
vector<int> count(len,1);
int imax=0;
for(int i=0;i<len;i++)
{
for(int j=0;j<i;j++)
if(nums[i]>nums[j])//说明i可以放到j后面
{
if(dp[j]+1>dp[i])
{
dp[i]=dp[j]+1;
count[i]=count[j];
}
else if(dp[j]+1==dp[i])
{
count[i]+=count[j];
}
}
imax=max(imax,dp[i]);//记录最长子序列的长度
}
int ans=0;
for(int i=0;i<len;i++)
if(dp[i]==imax)
ans+=count[i];
return ans;
}
};