• hdoj1257(DP-LIS/贪心)


    题目链接: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
    ",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
    ",len);
    28     }
    29     return 0;
    30 }

    个人觉得这道题是考察的第二种解法,但由于数据量不大,故用第一种方法也行。

  • 相关阅读:
    Java基础-四要素之一《继承》
    Java基础-四要素之一《多态》
    Java基础-四大特性理解(抽象、封装、继承、多态)
    Java基础-父类-子类执行顺序
    Java基础--重写(Overriding,覆盖)-重载(Overloading)
    Java基础-数据类型转换
    Java基础-转义字符
    Java基础-数据类型int,short,char,long,float,double,boolean,byte
    算法-科学计算法
    Java基础-JVM堆与栈
  • 原文地址:https://www.cnblogs.com/FrankChen831X/p/10402857.html
Copyright © 2020-2023  润新知