标签:数据 log rank -- blog 否则 因此 space php
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1257
方法1--贪心:
定义一个数组f[30005],由于题目没给数据量大小,故为了保险,开到最大(高度的最大值)。f[i]表示第i套系统最后一发导弹的值。边输入边处理就行,若当前值可以使用之前的系统则更新该系统最后一发导弹的高度值,否则使用新系统。要注意的地方是判断当前输入的值是否可以使用已经存在的系统时,应从第一个系统开始往后遍历,因为越前面的系统其最后一发导弹的高度越低。比如,当前有两个系统分别是“100 50”和“101 70”,若当前输入的是30,则选择第一套系统更好,因为后面输入的50—70之间的值就可以使用第二套系统,这个地方好好想一下,最后输出系统个数就行了。详见代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n,f[30005]; 5 6 int main(){ 7 while(scanf("%d",&n)!=EOF){ 8 int k=0,tmp; 9 bool suc; 10 while(n--){ 11 suc=false; 12 scanf("%d",&tmp); 13 for(int i=1;i<=k;i++) 14 if(tmp<=f[i]){ 15 f[i]=tmp; 16 suc=true; 17 break; 18 } 19 if(!suc) 20 f[++k]=tmp; 21 } 22 printf("%d\n",k); 23 } 24 return 0; 25 }
方法二--DP—LIS:
其实这道题的解就是数据的LIS的长度,关于LIS解法可以参考我的另一篇随笔:https://www.cnblogs.com/FrankChen831X/p/10384238.html。
仔细想一下LIS的O(nlogn)解法过程,实际上每次长度增加时就是本题的系统要加一,因此最终的LIS的每一个值就是每一个系统的最后一发导弹的高度值,每一个位置的更新过程就是每个系统对应的导弹的高度值。这里可以进一步加深对LIS解法过程的理解。代码如下:
1 #include<bits/stdc++.h> 2 using namespace std; 3 4 int n,f[30005]; 5 6 int main(){ 7 while(scanf("%d",&n)!=EOF){ 8 int tmp,len=0; 9 scanf("%d",&tmp); 10 n--; 11 f[++len]=tmp; 12 while(n--){ 13 scanf("%d",&tmp); 14 if(tmp>f[len]) f[++len]=tmp; 15 else if(tmp<=f[1]) f[1]=tmp; 16 else{ 17 int l=1,r=len,m; 18 while(l<=r){ 19 m=(l+r)/2; 20 if(tmp>f[m-1]&&tmp<=f[m]) break; 21 if(tmp<f[m]) r=m-1; 22 else l=m+1; 23 } 24 f[m]=tmp; 25 } 26 } 27 printf("%d\n",len); 28 } 29 return 0; 30 }
个人觉得这道题是考察的第二种解法,但由于数据量不大,故用第一种方法也行。
标签:数据 log rank -- blog 否则 因此 space php
原文地址:https://www.cnblogs.com/FrankChen831X/p/10402857.html