673.最長増加部分列の数
ソートされていない整数配列が与えられた場合、最長増加部分列の数を見つけます。
示例 1:
输入: [1,3,5,4,7]
输出: 2
解释: 有两个最长递增子序列,分别是 [1, 3, 4, 7] 和[1, 3, 5, 7]。
示例 2:
输入: [2,2,2,2,2]
输出: 5
解释: 最长递增子序列的长度是1,并且存在5个子序列的长度为1,因此输出5。
注意: 给定的数组长度不超过 2000 并且结果一定是32位有符号整数。
回答:
この問題は、動的計画法のアイデアを使用して行うことができます。
1つ目は、問題を分解し、最も長く増加するサブシーケンスの数を要求することです。最後の要素で終わる最も長く増加するサブシーケンスと、最後の要素で終わらない最も長く増加するサブシーケンスに分割できます。次に、2つを尋ねることができます。最大の場合。
したがって、同じことがどのような状況にも当てはまります。
dp [i]は、i番目の要素で終わる最長増加部分列として定義できます。これは、i番目の要素で終わるため、多くの場合に分割されます。つまり、前の要素に接続されます。(この質問は任意につなげることができるので)前にi-1があるので、毎回列挙して前の結果と比較してください。
我々が得ることができるので、状態遷移方程式:
DP [I] = MAX(DP [I]、DP [J] +1);
(<JをI-1 =)
i番目ではなくi-1、i-2、i-3 ...で終了することもできるので、各dp [i]を計算した後、前の各dp [i]を追加する必要があります。 dp [i-1]、dp [i-1]、dp [i-3] ...
そして上記の操作は面倒なので、変数を使用して最初のいくつかの最大値を記録し、最大値およびdp [i]。
コード:
int Max(int x,int y)
{
return x>y?x:y;
}
int findNumberOfLIS(int* nums, int numsSize){
int dp[numsSize+1];
dp[1] = 1;
int max = INT_MIN;
for(int i=0;i<numsSize;i++)
{
for(int j=0;j<i;j++)
{
dp[i] = Max(dp[i],dp[j]+1);
}
max = Max(max,dp[i]);
}
return max;
}