• Codeforces 777E


    题目链接:http://codeforces.com/problemset/problem/777/E

    题意:有n个环给你内环半径、外环半径和高度,叠这些环还要满足以下要求:

        ①:下面的环的外径要>=上面的环

        ②:环不能掉下去,所以下面的环的内径要<上面的环的外径

        ③:叠出最大高度

    思路:贪心思想,先把这些环按外径从大到小,内径从大到小排好序,内径从大到小是为了尽可能让后面的环能放上去。接下来就可以用栈模拟了,放1~n个环的时每次都要判断,如果当前最顶上的环的内径大于我要放的环的内径也就是放不上去,那就把顶上的环出栈,一直循环直到能放上去为止,再把当前环入栈。然后每次都比较一下高度和,得出最大高度。为什么可以用栈写?因为我们已经知道前面的环叠不上后面的环肯定也叠不上,因为后面的环外径肯定<=前面的环,那把栈当成已经建好的塔,如果环放不上去,为了后面可以继续放,那可以拆了一部分重建。

      这是开始没用栈的无脑代码从头到尾遍历了一遍,直接超时,心塞- -、、:

      

    #include<iostream>
    #include<algorithm> 
    #include<string>
    using namespace std;
    const int N=1e5+5;
    typedef long long ll;
    struct node{
        int in;
        int out;
        int h;
    }a[N];
    ll dp[N];
    
    bool cmp(node a,node b){
        return a.out==b.out?a.in>b.in:a.out>b.out;
    }
    
    int main(){
        ll n,ans=0;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i].in>>a[i].out>>a[i].h;
            if(a[i].h>ans)
                ans=a[i].h;
        }
        sort(a+1,a+1+n,cmp);
    //    cout<<endl;
    //    for(int i=1;i<=n;i++){
    //        cout<<a[i].in<<" "<<a[i].out<<" "<<a[i].h<<endl;
    //    }
        for(int i=1;i<=n;i++){
            dp[i]=a[i].h;
            for(int j=1;j<i;j++){
                if(a[i].out>=a[j].in)
                    dp[i]=max(dp[i],dp[j]+a[i].h);
            }
            ans=max(ans,dp[i]); 
        }
        cout<<ans<<endl;
    }

    这是用栈写的:

    #include<iostream>
    #include<algorithm> 
    #include<stack>
    using namespace std;
    const int N=1e5+5;
    typedef long long ll;
    struct node{
        int in;
        int out;
        int h;
    }a[N];
    ll dp[N];
    
    bool cmp(node a,node b){
        return a.out==b.out?a.in>b.in:a.out>b.out;
    }
    int main(){
        ll n;
        stack<node>s;
        cin>>n;
        for(int i=1;i<=n;i++){
            cin>>a[i].in>>a[i].out>>a[i].h;
        }
        sort(a+1,a+1+n,cmp);
    //    cout<<endl;
    //    for(int i=1;i<=n;i++){
    //        cout<<a[i].in<<" "<<a[i].out<<" "<<a[i].h<<endl;
    //    }
        ll sum=0,ans=0;
        for(int i=1;i<=n;i++){
            while(!s.empty()&&a[i].out<=s.top().in){//判断是否能叠上去,不能的话就把最顶上的环拿下来 
                sum-=s.top().h;
                s.pop();
            }
            sum+=a[i].h;
            s.push(a[i]);
            ans=max(ans,sum); //比较最大高度 
        }
        cout<<ans<<endl;
    }
  • 相关阅读:
    SHAREPOINT2007 文档库中通过EMAIL发送文档URL为乱码的解决方法
    ReadTrace
    实战分区表:SQL Server 2k5&2k8系列
    mssql 如何创建跟踪
    SQL Server自定义异常的使用raiserror
    SQL Server 2008内存及I/O性能监控
    实战 SQL Server 2008 数据库误删除数据的恢复
    MSSQL常用性能測試語句
    sqlserver 2008 设置了镜像 如何收缩日志文件
    复制订阅错误处理。
  • 原文地址:https://www.cnblogs.com/fu3638/p/6750410.html
Copyright © 2020-2023  润新知