lis怎么编程

时间:2025-01-24 15:52:06 网络游戏

编程实现最长上升子序列(LIS)的方法有多种,以下提供两种常见的方法:

方法一:动态规划

定义状态

设 `dp[i]` 表示以 `a[i]` 为结尾的最长上升子序列的长度。

状态转移方程

对于每个元素 `a[i]`,遍历其之前的所有元素 `a[j]`(其中 `j < i`),如果 `a[j] < a[i]`,则 `dp[i] = max(dp[i], dp[j] + 1)`。

初始化

`dp[i] = 1`,因为每个元素本身可以构成长度为1的上升子序列。

计算顺序

从左到右依次计算每个 `dp[i]`。

结果

最终 `dp` 数组中的最大值即为最长上升子序列的长度。

示例代码

```cpp

include

include

include

using namespace std;

int lis_dp(vector& nums) {

int n = nums.size();

vector dp(n, 1);

int max_len = 1;

for (int i = 1; i < n; ++i) {

for (int j = 0; j < i; ++j) {

if (nums[j] < nums[i]) {

dp[i] = max(dp[i], dp[j] + 1);

}

}

max_len = max(max_len, dp[i]);

}

return max_len;

}

int main() {

vector nums = {1, 7, 5, 6, 9, 2, 4};

cout << "Length of LIS is " << lis_dp(nums) << endl;

return 0;

}

```

方法二:二分查找

定义状态

设 `dp[i]` 表示以 `a[i]` 为结尾的最长上升子序列的长度。

设 `len` 表示当前找到的最长上升子序列的长度。

状态转移方程

使用二分查找找到 `dp[i]` 的最大值。

维护一个数组 `d`,其中 `d[len]` 表示长度为 `len` 的上升子序列的最小末尾元素。

初始化

`dp[i] = 1`,因为每个元素本身可以构成长度为1的上升子序列。

`len = 1`,`d = a`。

计算顺序

从左到右依次计算每个 `dp[i]`,并更新 `d` 数组。

结果

最终 `len` 即为最长上升子序列的长度。

示例代码

```cpp

include

include

include

using namespace std;

int lis_binary_search(vector& nums) {

int n = nums.size();

vector dp(n, 1);

int len = 1;

vector d(n + 1, 0);

d = nums;

for (int i = 1; i < n; ++i) {

if (nums[i] > d[len]) {

d[++len] = nums[i];

} else {

auto it = lower_bound(d.begin(), d.begin() + len + 1, nums[i]);

*it = nums[i];

}

}

return len;

}

int main() {

vector nums = {1, 7, 5, 6, 9, 2, 4};

cout << "Length of LIS is " << lis_binary_search(nums) << endl;

return 0;

}

```

编程语言选择

Java:适用于企业级应用程序,具有强大的跨平台性和可扩展性。

C:拥有强大的.NET框架支持,适合快速开发可靠的医院