NOIP2011は観光バス[グループを改善します]

含まれる複製元  https://blog.nowcoder.net/n/c3b27ff350044e53bd71acbf94e260f9  でヤンチャンスクール

タイトル説明

風光明媚な町、美しい景色のn個とY市。より多くの観光客が特にここに来ると、Y市は、特別に、より便利な輸送サービスを提供するために、観光客のためのツアーバスのために配置します。最初の0分でバスを観光する第1スポットに表示され、...... 2,3,4アトラクションのn個の数を行った順番に続きます。i番目の建玉から興味のあるI + 1にディ分を必要としています。任意の時点で、あなただけのバスで運転することができ、またはで観光スポットで待機しています。
総セットアップメートルの訪問者のを、各訪問者が1つの魅力から別の1つのアトラクションに到達するために移動する必要があり、私のゲストはアトラクションのBi(あい<バイ)を乗ることを期待して、スポット愛のTi分で来ました。すべての乗客は観光スポットが隣の魅力に出発行きの電車にいるから逸脱する必要があります後にスムーズに目的地に到達することができ、すべての乗客を有効にするには、バスはすべての駅で待機する必要があります。
乗客を下車する時間を負いません。
彼の目的地到着時刻マイナス彼は出発点に来た時と同じ乗客の旅行時間、。唯一の観光の車なので、時には他の乗客を待つために停止し、乗客はあまりにも長い移動時間について訴えています。だから、スマートドライバー Kバスのために設置さ窒素アクセラレータ、それぞれをマイナスディ1を作ることができる1種の促進を、使用してZZ。再使用可能なアクセルに対してディが、使用後Diが0以上であることを確認しなければなりません。

だから、 ZZはどのようにすべての乗客のための総旅行時間を最小限にするために、アクセラレータの使用を整理するには?

説明を入力します。

1行は、スペースで区切られた2つの整数のそれぞれの間に、3の整数N、M、Kです。それぞれが関心のポイント数、乗客数と窒素促進剤の数を表します。
最初の行は、2つの整数の間の空間によって分離された2 n-1の整数であり、それぞれ、それは必要にI + 1-アトラクションを結合し、i番目の関心、すなわち、Diをからi番目の時間を示します
3のTi、愛、バイの整数各m + 2行の3行、それぞれ2つの整数の間のスペースで区切られました。最初のi + 2行iがアトラクションを逸脱乗客に行った最初の時間を表し、観光名所の発着数のスポットの数。

出力説明

最小の総旅行時間を表す整数を含む1つのラインの合計。

サンプル入力  サンプル入力

3 3 2
1 4
0 1 3
1 1 2
5 2 3

サンプル出力

10

データ範囲とヒント

する 2アクセルD2を使用して、関心の時間の2〜3スポットから2分に変更しました。
第1バスで 1分間1番スポットから、2分、3番スポットに到達するために、2番スポットから番号7分を2スポット、最初の5分間に到達します。
最初の 1人の乗客の旅行時間7-0 = 7分。
最初の 2つの旅客時間2-1 = 1分。
最初の 3人の乗客の旅行時間7-5 = 2分。
合計時間 7 + 2 + 1 = 10分。

データ範囲
のためにデータの10%、K = 0;
のためのデータの20%、K = 1;
のためにデータの40%、2≤N≤50,1≤m≤ 1,000,0≤K≤20.0≤ディ≤ Tiの≤500≤10,0;
のためのデータの60%、1≤N≤100,1≤m≤のTi≤万≤100,0≤1,000,0≤K≤ディ≤100,0;
のための 100%にデータ、 N-1,000≤≤≤1つの≤Mさ≤K≤のTi≤ディ≤100,0≤100,000≤10,000,0 100,000、

 考え

Mouwang牛クラスに住んで、チャンヤンの学校の首長は、この質問について話しました、インターネットはあまりにも完璧ではない証明し、彼は、自分自身を少し証明する、彼にネットワーク全体の開始に従って強すぎます

おそらくそれをも、神は私はまだ本当に理解していなかった、あまりにも強い走りました

ACコード

 1 #include <iostream>
 2 #include <algorithm>
 3 using namespace std; const int N = 1010,
 4     M = 10010;
 5  
 6 int n, m, k;
 7 int d[N];
 8 int t[M], a[M], b[M];
 9 int tm[N], last[N];
10 int sum[N];
11 int reduce[N];
12  
13 int main()
14 {
15     scanf("%d%d%d", &n, &m, &k);
16     for (int i = 1; i < n; i++) scanf("%d", &d[i]);
17     for (int i = 0; i < m; i++)
18     {
19         scanf("%d%d%d", &t[i], &a[i], &b[i]);
20         last[a[i]] = max(last[a[i]], t[i]);
21         sum[b[i]]++;
22     }
23  
24     for (int i = 1; i <= n; i++) tm[i] = max(tm[i - 1], last[i - 1]) + d[i - 1];
25  
26     while (k--)
27     {
28         for (int i = n; i >= 2; i--)
29             if (!d[i - 1]) reduce[i - 1] = 0;
30             else
31             {
32                 reduce[i - 1] = sum[i];
33                 if (tm[i] > last[i]) reduce[i - 1] += reduce[i];
34             }
35  
36         int p = 0;
37         for (int i = 1; i < n; i++)
38             if (reduce[p] < reduce[i])
39                 p = i;
40  
41         if (!p) break;
42         d[p]--;
43         for (int i = p + 1; i <= n; i++) tm[i] = max(tm[i - 1], last[i - 1]) + d[i - 1];
44     }
45  
46     int res = 0;
47     for (int i = 0; i < m; i++) res += tm[b[i]] - t[i];
48  
49     printf("%d\n", res);
50     return 0;
51 }

 

おすすめ

転載: www.cnblogs.com/Snowindfly/p/11279304.html