LIS/LCS的几种写法(最长上升子序列/最长公共子序列)
LIS有三种写法,此文章仅写出两种复杂度分别为(n^2)和(nlogn)
第一种写法O(n^2)
int num[1000], n,out=0;//n为字母个数,num存放数字,out为最长上升子序列的长度 int dp[1000];//dp存放该数字为最后一个数字的时候最长上升子序列的长度 cin >> n; for (int i = 0; i < n; i++)//输入数字 { cin >> num[i]; } for (int i = 0; i < n; i++)//初始化dp数组 { dp[i] = 1; } for (int i = 0; i < n; i++) { for (int f = 0; f < i; f++) { if (num[f] < num[i])//当num[i]大于num[f]时即上升 { dp[i] = max(dp[i], dp[f] + 1); } } out = max(out, dp[i]); } cout << out << endl;
第二种写法O(nlogn)
int num[1000], n, len; int dp[1000]; cin >> n; for (int i = 1; i <= n; i++) { cin >> num[i]; } dp[1] = num[1]; len = 1; for (int i = 2; i <= n; i++) { if (num[i] > dp[len])//有数字比当前末尾的数字大则len++ { dp[++len] = num[i]; } else { int l = 0, r = len, mid; while (l <= r)//二分 { mid = (l + r) >> 1; if (dp[mid] >= num[i]) { r = mid - 1; } else { l = mid + 1; } } dp[l] = num[i]; } } cout << len << endl;
LCS利用动态规划实现
int dp[100][100] = { 0 }; string x, y; cin >> x >> y; for (int i = 0; i < x.length(); i++) { for (int f = 0; f < y.length(); f++) { if (x[i] == y[f]) { dp[i + 1][f + 1] = dp[i][f] + 1; } else { dp[i + 1][f + 1] = max(dp[i][f + 1], dp[i + 1][f]); } } } cout << dp[x.length()][y.length()] << endl;