動態規划——最長升序子序列及其個數


673. 最長遞增子序列的個數
1
public int findNumberOfLIS(int[] nums) { 2 int n=nums.length; 3 if(n==0||n==1)return n; 4 int []dp=new int[n]; 5 int []cnt=new int[n]; 6 int i,j,max=0,res=0; 7 Arrays.fill(dp, 1); 8 Arrays.fill(cnt, 1); 9 for(i=1;i<n;i++){ 10 for(j=0;j<i;j++){ 11 if(nums[i]>nums[j]&&dp[i]<=dp[j]){ 12 dp[i]=dp[j]+1; 13 cnt[i]=cnt[j]; 14 }else if(nums[i]>nums[j]&&dp[i]==dp[j]+1) 15 cnt[i]+=cnt[j]; 16 } 17 max=Math.max(dp[i],max); 18 } 19 for(i=0;i<n;i++) 20 if(dp[i]==max) 21 res+=cnt[i]; 22 return res; 23 }

   首先要清楚dp[i]存放的是什么。之前想當然的認為dp[i]=0..i最長的自增子序列長度,若是如此,那么dp[]便為非降序數組,然而事實並非如此。通過查看dp[]的增長方式便知,其需要滿足兩個條件nums[i]>nums[j]&&dp[i]<=dp[j],關鍵的是dp[i]<=dp[j],若沒有這個條件,在多次迭代后會有許多重復計算。而最長子序列個數的增長是建立在所有前序狀態上的,也就是組合的思想。當nums[i]>nums[j]&&dp[i]==dp[j]+1時,也就是再一次滿足了最長子序列的條件,但是並不改變當前dp[i]的值(避免多重計算)此時,當前最長子序列增長。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM