题面
世界需要和平,人民向往和平。
但是,历史上,很多和平都是靠战争换来的。
Z国和Y国开战了,Z国已经向Y国摆好了n门炮弹,记为x1,x2,⋯,xn,这n门炮弹是按自然顺序有序摆放。开战后,可以选择哪些炮弹要发射,哪些不发射,发射多门炮弹时,发射的顺序必须跟原始炮弹摆放的相对顺序一致,但连续发射的两门炮弹不一定在原始摆放顺序中也是连续的。假设每一门炮弹的杀伤力为1,后发射的炮弹的射程大于前面发射的炮弹,其杀伤力才能展现,否则,该门炮弹发射就不具备杀伤力。
你是该场战争的指挥官,如何安排炮弹的发射顺序,使得杀伤力最大。
输入
第一个数为炮弹门数n(1≤n≤25000)。
接下来1行,包括n个正整数,第i个数表示摆放的第i门炮弹的发射射程k(0≤k≤1000000)。
输出
输出一行,是一个整数,表示该场战争发射炮弹形成的杀伤力。
输入样例
3 16 10 15
输出样例
2
样例解释
发射第2门(射程为10)和第3门(射程为15)炮弹。
代码(n^2解法 最长上升子序列)
#include <iostream> using namespace std; unsigned int dp[500005],a[500005],ans; int main() { int n; cin >> n; a[0] = 0x3f3f3f3f; ans = 0; for(int i = 1; i <= n; i++) cin >> a[i]; for(int i = 1; i <= n; i++) { dp[i] = 1; for(int j = 0; j < i ; j++) if(a[i] > a[j]) dp[i] = max(dp[i], dp[j] + 1); ans = max(ans,dp[i]); } cout<<ans<<endl; return 0; }
代码 nlogn解法
#include <iostream> using namespace std; unsigned int f[500005],a[500005]; int main() { int n,ans = 0; cin >> n; for(int i = 0; i < n; i++) cin >> a[i]; for(int i = 0; i < n; i++) { if(a[i] > f[ans]){ f[++ans] = a[i]; } else { int l = 0, r = ans; while(l < r) { int mid = (l + r )>> 1; if(f[mid] >= a[i]) r = mid; else l = mid +1; } f[l] = a[i]; } } cout<<ans<<endl; return 0; }