1010. 拦截导弹(动态规划,最长上升子序列模型)
解法一:
#include <bits/stdc++.h> using namespace std; const int N = 30030; int a[N], f[N], b[N]; int n; int main() { while(cin >> a[n]) n++; int res = 0, cnt = 0; for(int i = 0; i < n; i++) { f[i] = 1; for(int j = i - 1; j > - 1; j--) { if(a[i] <= a[j]) { f[i] = max(f[i],f[j]+1); } } //贪心流程: //从前往后扫描每个数,对于每个数: //情况1:如果现有的子序列的结果都小于当前数, 则创建新子序列; //情况2: 将当前数放到结尾大于等于它的最小的子序列后面; int t = 0; while(t < cnt && a[i] > b[t]) t++; if(t == cnt) b[cnt++] = a[i]; else b[t] = a[i]; res = max(res,f[i]); } cout << res << endl << cnt << endl; return 0; }
解法二:
#include <bits/stdc++.h> using namespace std; const int N = 30030; int a[N], f[N]; int n; int main() { while(cin >> a[n]) n++; int res = 0; for(int i = 0; i < n; i++) { f[i] = 1; for(int j = i - 1; j > - 1; j--) { if(a[i] <= a[j]) { f[i] = max(f[i],f[j]+1); } } res = max(res,f[i]); } cout << res << endl; int res1 = 0; for(int i = 0; i < n; i++) { f[i] = 1; for(int j = i - 1; j > -1; j--) { if(a[i] > a[j]) { f[i] = max(f[i],f[j] + 1); } } res1 = max(res1,f[i]); } cout << res1 << endl; return 0; }