NOIPシミュレーション演習9

NOIPシミュレーション演習9

  • より簡単。一つのAK。

運動プログラム

説明

  • 体は革命の首都である、ではないので、強烈な研究の、健康を犠牲にして、一日中パソコンの前でOIers
    健康問題。X小さなデザイン、独自の運動プログラムが、彼は他の言葉で、計画が実現可能であるかどうかわからなかった
    ので、小さなxは彼を助けてください、もし貧しい計画は彼の強さの超過を行うことができること。
    ある日1440分、とても小さいXリストのすべての日1〜1440分計画。
    物理的に小さな整数でXは、彼は同時に、毎分小さなX、スケジュールに従って行使するだろうと述べ
    体力が自動的に1つずつ増加します。分小さなxの物理的な終わりがゼロより小さい場合、かわいそうX
    上では使い古さ......

入力

  • 最初の行は、スペースで区切られた二つの整数であるN、M、及びそれぞれが小の初期計画物理値X表す
    アイテムの数。
    m行から開始して2行目には、各行が運動プログラムを記述する:名、開始時間の終わり
    (スペースで区切られた)分あたりインターB、物理的な消費は、プロジェクトから出発して、B、分の先頭を示します分
    後半ベル終わり。開始時刻に応じた運動プログラム昇順が指定され、二つのプロジェクトは、時間の競合ではありません
    状況。

出力

  • プロジェクトは、出力「受理」の最初の行、当日の出力の2行目に実現可能である場合、出力は、2つの行を含んでいる
    「ランタイムエラー」出力のそれ以外の場合は最初の行、最初の数分での出力の2行目、最後の物理残った後に
    鐘疲れ死にました。

サンプル入力

バスケットボール1 10 1

サンプル出力

容認されました

1140

ソリューション:

  • シミュレーション... ...
#include <iostream>
#include <cstdio>
#include <string>
using namespace std;

int n, m;
int a[2005];

int main()
{
    cin >> n >> m;
    for(int i = 1; i <= m; i++)
    {
        string t; cin >> t;
        int u, v, w;
        cin >> u >> v >> w;
        for(int j = u; j <= v; j++) a[j] += w;
    }
    for(int i = 1; i <= 1440; i++)
    {
        n++, n -= a[i];
        if(n <= 0) {cout << "Runtime Error\n" << i; return 0;}
    }
    cout << "Accepted\n" << n;
    return 0;
}

ウォークラフト

説明

  • すごい小さなxはエクスタシーである
    彼は、死の騎士グールの制御にあったとn(1〜nの番号が付け)狩りに行くために
    、死の騎士をグールのにHPを補完することができ、「デス・スパイラル」と呼ばれる、魔法を持っている
    敵との戦いのコースグールは、グールHPが減少します、攻撃する
    、小さなxは常に自分自身の力、HPのマルチグールどのくらいのHPの、すなわちk値の状況を知りたい
    どのように呪文をキャストするかを決定するために、
    彼を助けるために誰かを尋ねます: )
    あなたに送られる信号の3種類の入力データにおけるパフォーマンスのスペースをアンダースコア:(小さなx)の
    A_i_aは、i番目のグールに送信された敵の攻撃を表し、i番目のグールはポイント失った
    場合は、HPをそれは、その後、グールは(アンデッドが死にかけている)死亡したHP <= 0です。
    敵は死んでグールを攻撃しません。
    C_i_aはデスナイトは、i番目のグールに死のスパイラルをリリース表し、それがポイントのHPを追加します。
    HPは上限値ではありません。
    デスナイト死コイルが死んでグールに発行されることはありません
    あなたは小さなXにクエリを発行表しQ_k

入力

  • 最初の行は、正の整数N
    N Nの整数を表し、後の初期グールHPの
    値が正の整数mのある
    放射されたX M行当たり少しの信号線

出力

  • 各問い合わせ小さなxについて、K-HPマルチグールの出力どのくらいのHP、もしグール合計
    Kの不足、出力-1。それぞれの行の数。
    出力の最後の行数:戦いの後、残りのグールの数

サンプル入力

5

1 2 3

4 5

10

Q 2

4 6

C 1〜4

Q 2

2 1

3 3

1 3

Q 4

C 2~10

Q 1

サンプル出力

4

5

-1

11

3

ソリューション:

  • 裸木問題のバランスをとります。私はFHQ-treapで実現しています。
  • 各修飾アプローチは、改正前にポイントを削除し、その後変性ポイントを追加することです。
#include <iostream>
#include <cstdio>
#include <cstdlib>
#define N 30005
using namespace std;

struct T {int l, r, val, dat, size;} t[N * 4];
int n, m, root, x, y, z, tot, now;
int a[N];

int read()
{
    int x = 0; char c = getchar();
    while(c < '0' || c > '9') c = getchar();
    while(c >= '0' && c <= '9') {x = x * 10 + c - '0'; c = getchar();}
    return x;
}

int New(int val)
{
    t[++tot].val = val;
    t[tot].dat = rand();
    t[tot].size = 1;
    return tot;
}

void up(int p) {t[p].size = t[t[p].l].size + t[t[p].r].size + 1;}

void split(int p, int val, int &x, int &y)
{
    if(!p) {x = y = 0; return;}
    if(t[p].val <= val) x = p, split(t[p].r, val, t[p].r, y);
    else y = p, split(t[p].l, val, x, t[p].l);
    up(p);
}

int merge(int x, int y)
{
    if(!x || !y) return x + y;
    if(t[x].dat > t[y].dat)
    {
        t[x].r = merge(t[x].r, y);
        up(x); return x;
    }
    else
    {
        t[y].l = merge(x, t[y].l);
        up(y); return y;
    }
}

void insert(int val)
{
    split(root, val - 1, x, y);
    root = merge(merge(x, New(val)), y);
}

void erase(int val)
{
    split(root, val, x, z);
    split(x, val - 1, x, y);
    y = merge(t[y].l, t[y].r);
    root = merge(merge(x, y), z);
}

int valOfRank(int rank)
{
    int p = root;
    while(p)
    {
        if(t[t[p].l].size + 1 == rank) break;
        else if(t[t[p].l].size >= rank) p = t[p].l;
        else rank -= t[t[p].l].size + 1, p = t[p].r;
    }
    return t[p].val;
}

int main()
{
    cin >> n, now = n;
    for(int i = 1; i <= n; i++)
    {
        a[i] = read();
        insert(a[i]);
    }
    cin >> m;
    for(int i = 1; i <= m; i++)
    {
        char c[3]; scanf("%s", c);
        if(c[0] == 'A')
        {
            int pos = read(), val = read();
            erase(a[pos]);
            a[pos] -= val;
            if(a[pos] <= 0) now--;
            else insert(a[pos]);
        }
        else if(c[0] == 'C')
        {
            int pos = read(), val = read();
            erase(a[pos]);
            a[pos] += val;
            insert(a[pos]);
        }
        else if(c[0] == 'Q')
        {
            int rank = read();
            if(now < rank) printf("-1\n");
            else printf("%d\n", valOfRank(now - rank + 1));
        }
    }
    cout << now;
    return 0;
}

ディアブロ

説明

  • ディアブロIでのボーリング小さなX ...遊んで
    n個の魔法でゲームのヒーローを
    各魔法のいくつかのレベルに分け、魔法は(0を除く)は、i番目のP [i]のレベルがあり
    、魔法ごとにそれぞれのを濃度効果値は、私は魔法の効果があるステージのJた
    W [i]は[J]魔法を、1リットルのそれぞれの魔法を必要
    後マジック金、i番目のトランストリップを必要としますC [i]の価格
    (修飾子のない少年)とわずかのxメートルの金貨は、
    あなたのタスクは、小さなxは、すべての魔法の値とほとんどの魔法の効果にするために本を購入する方法を決定支援することです
    大きな
    すべての魔法の先頭に0を効果は0であります

入力

  • NM 2スペースで区切られた整数の最初の行
    魔法以下の説明N N行
    I + 1-i行目は、次の形式マジックに記載されている
    C [i]とP [i]は W [i]を[1]、W [i]は[2] ... W [i]と [P [i]は]

出力

  • 整数の第1の出力ライン、最大の効果の、すなわち値。
    行した後、n個の出力あなたのプログラム:
    私は+ 1番目のラインは、V [i]は、あなたがマジックV [i]の段階を学ぶことにしたi番目の意味整数持つ
    複数のソリューションの出力は、彼らがグループの最小値を過ごす場合
    のソリューションよりも多くの場合を出力のグループのいずれかの

サンプル入力

3 10

1 3 1 2 2

2 3 2 4 6

3 3 2 1 10

サンプル出力

11

1

0

3

ソリューション:

  • リニアDP。
  • 設定しDP(I、J)は効果得られた金の最大値と魔法のI、Jの前に処理されます。
  • 1によって - この最適値を取ることによって、その後のアイテムの状態(iは1)は、記事のさまざまな形態をとります。
  • 比較的容易に、主に輸出プログラム。
  • Iは、(i、j)を使用して考えた同期 DP(i、j)はその記事に、得られた場合には、記録時、オペレータは、(i、j)をDPします。
  • [OK]を、取得します。
#include <iostream>
#include <cstdio>
#include <algorithm>
#define N 2005
using namespace std;

struct Ans {int id, lev;} ans[N];
struct A {int val, id, lev;} a[N][N];
int n, T;
int cnt[N];
int w[N][N], v[N][N], dp[N][N];

bool cmp(Ans x, Ans y) {return x.id < y.id;}

int main()
{
    cin >> n >> T;
    for(int i = 1; i <= n; i++)
    {
        int c; cin >> c;
        int p; cin >> p;
        cnt[i] = p;
        for(int j = 1; j <= p; j++)
            cin >> v[i][j], w[i][j] = c * j;
    }
    for(int i = 1; i <= n; i++)
        for(int j = 0; j <= T; j++)
            for(int k = 0; k <= cnt[i]; k++)
                if(j - w[i][k] >= 0)
                    if(dp[i - 1][j - w[i][k]] + v[i][k] > dp[i][j])
                    {
                        dp[i][j] = dp[i - 1][j - w[i][k]] + v[i][k];
                        a[i][j].id = i, a[i][j].lev = k;
                        a[i][j].val = w[i][k];
                    }
                    else if(dp[i - 1][j - w[i][k]] + v[i][k] == dp[i][j] && w[i][k] < a[i][j].val)
                    {
                        dp[i][j] = dp[i - 1][j - w[i][k]] + v[i][k];
                        a[i][j].id = i, a[i][j].lev = k;
                        a[i][j].val = w[i][k];
                    }
    cout << dp[n][T] << endl;
    int now = T;
    for(int i = n; i >= 1; i--)
    {
        ans[i].id = a[i][now].id;
        ans[i].lev = a[i][now].lev;
        now = now - a[i][now].val;
    }
    sort(ans + 1, ans + 1 + n, cmp);
    for(int i = 1; i <= n; i++) cout << ans[i].lev << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/BigYellowDog/p/11620615.html