1010. 拦截导弹
分析
就是最长不上升子序列
再加一问,最少需要几套系统才能拦截所有导弹?
贪心:
从前往后扫描每个数,对于每个数:
情况1:如果现有子序列结尾都小于当前数,则创建新的子序列
情况2:将当前数放在结尾大于等于它的最小的子序列后面。
code(第二问贪心)
#include <iostream>
using namespace std;
const int N = 1010;
int a[N], f[N], n, g[N];
int main(){
while (cin >> a[n]) n ++ ;
for (int i = 0; i < n; i ++ ){
f[i] = 1;
for (int j = 0; j < i; j ++)
if (a[j] >= a[i])
f[i] = max(f[i], f[j] + 1);
}
int res = 1;
for (int i = 0; i < n; i ++ ) res = max(res, f[i]);
cout << res << endl;
int cnt = 0;//g数组长度
for (int i = 0; i < n; i ++ ){
int k = 0;
while (k < cnt && g[k] < a[i]) k ++;// 因为需要把a[i]接到 >= a[i]的最小的数后面.
g[k] = a[i];
if (k >= cnt) cnt ++;
}
cout << cnt << endl;
return 0;
}
code2
#include <iostream>
using namespace std;
const int N = 1010;
int a[N], f[N], n, g[N];
int main(){
while (cin >> a[n]) n ++ ;
for (int i = 0; i < n; i ++ ){
f[i] = 1;
for (int j = 0; j < i; j ++)
if (a[j] >= a[i])
f[i] = max(f[i], f[j] + 1);
}
int res = 1;
for (int i = 0; i < n; i ++ ) res = max(res, f[i]);
cout << res << endl;
for (int i = 0; i < n; i ++ ){
g[i] = 1;
for (int j = 0; j < i; j ++ )
if (a[j] < a[i])
g[i] = max(g[i], g[j] + 1);
}
res = 1;
for (int i = 0; i < n; i ++ ) res = max(res, g[i]);
cout << res << endl;
return 0;
}