Codeforces 777E:ハノイ工場(貪欲)

もちろん、ハノイタワーズについての有名なタスクを聞いたことがあるが、あなたはこの素晴らしいゲームのためのリングを生産する特殊な工場があることをご存知でしたか?むかしむかし、古代エジプトの支配者は、できるだけ高いタワーを作成するために、ハノイ工場の労働者を命じました。彼らはすでに生産のリングを使用して、この新しいタワーを作成する必要がありましたので、このような奇妙な順番にサービスを提供する準備ができていませんでした。

あります\(N \)は、工場の株式に鳴ります。\(iは\)番目のリングは、内側半径有し\(a_iをを\) 外半径\(b_i \)と高さ(\ H_I \) 目標は、リングのいくつかのサブセットを選択し、以下の条件が満たされるようにそれらを配置することです。

  • 外側の半径は1つが置くことができる、すなわち非増加列を形成する(J \)\を上番目のリング(私は\)\番目のリングを場合のみ\(b_j≤b_i \)
  • リングは、一方を他方に落ちるべきではありません。それは1つがリングに置くことができることを意味\(j個\)をリング上で\(私は\)場合のみ\(b_j> a_iを\)
  • 使用されているすべてのリングの高さの合計は、可能な最大値でなければなりません。

入力

入力の最初の行は、単一の整数含ま\(N(1≤N 100 000≤)\)工場の在庫中の環の数を- 。

\(iは\)次の番目の\(N \)線は三つの整数が含ま\(a_iを、b_i \)\(≤H_I(1 a_iを、b_i、H_I 9 ^ 10≤、b_i> a_iを)\) -内側半径、外側半径との高さ\(iは\)それぞれ番目リング。

出力

得られる塔の最大の高さ - 1つの整数を出力します。

入力

3
1 5 1
2 6 2
3 7 3

出力

6

入力

4
1 2 1
1 3 3
4 6 2
5 7 1

出力

4

注意

最初のサンプルでは、最適な解決策は、すべてのリングを取り、順番にお互いに入れることです\(3、2、1 \)

第二のサンプルでは、一方のリングに置くことができる\(3 \)をリング上で\(4 \)と高さのタワーを取得\(3 \) または環置く\(1 \)をリング上で\(2 \)と高さのタワーを取得\(4 \を)

問題の意味

そこ\(N- \)の中空シリンダー、\(Iは\)であったシリンダの内径、外径および高さ:\(a_iを、B_i、H_I \) 以下内径よりも下へ、非減少の外径は、上記の外径より小さい:これらのシリンダは、要求を積み上げます。Q.どのように高く盛り上げことができます

考え

貪欲

外径および内径が同じであれば高さの降順でソート、同じ外径、降順により内径場合、降順の外径を押します。最初の場合は満たすことができますどの\(私は\) 1を取ることができない、そして最初の(I + 1 \)\ 1は取らないしなければならない、と最高の高さに行ってきました

その後、維持するために、スタックと。シリンダは、スタックの最上位に置くことができますプラス、入れない場合、それはシリンダー内のスタックの全高を維持するために、先頭の要素をポップアップ表示されますたびに、最大値をとります

コード

#include <bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define ms(a,b) memset(a,b,sizeof(a))
const int inf=0x3f3f3f3f;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e6+10;
const int mod=1e9+7;
const int maxm=1e3+10;
using namespace std;
struct wzy
{
    int a,b,h;
}p[maxn];
bool cmp(wzy u,wzy v)
{
    if(u.b==v.b)
    {
        if(u.a==v.a)
            return u.h>v.h;
        return u.a>v.a;
    }
    return u.b>v.b;
}
int main(int argc, char const *argv[])
{
    #ifndef ONLINE_JUDGE
        freopen("/home/wzy/in.txt", "r", stdin);
        freopen("/home/wzy/out.txt", "w", stdout);
        srand((unsigned int)time(NULL));
    #endif
    ios::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>p[i].a>>p[i].b>>p[i].h;
    sort(p+1,p+1+n,cmp);
    ll ans=1LL*p[1].h;
    ll sum=1LL*p[1].h;
    stack<wzy>st;
    st.push(p[1]);
    for(int i=2;i<=n;i++)    
    {
        while(!st.empty()&&(st.top().a>=p[i].b||st.top().b<p[i].b))
        {
            sum-=1LL*st.top().h;
            st.pop();
        }
        sum+=1LL*p[i].h;
        st.push(p[i]);
        ans=max(ans,sum);
    }
    cout<<ans<<endl;
    #ifndef ONLINE_JUDGE
        cerr<<"Time elapsed: "<<1.0*clock()/CLOCKS_PER_SEC<<" s."<<endl;
    #endif
    return 0;
}

おすすめ

転載: www.cnblogs.com/Friends-A/p/11571769.html