羅区P2627は、芝生の問題解決を刈ります

芝刈りP2627

タイトル説明

町では一年前に最高の芝生のゲームに勝った、ファームジョンは芝を刈ら決して、怠惰になりました。今、最高の芝生のゲームの新ラウンドが始まった、ファームジョンは再び勝利したいと考えています。

しかし、非常に汚いファームジョンの芝生は、それゆえ、ファームジョンは彼の牛が仕事を得るためにさせることができます。ファームジョンは、行のN(1 <= N <=10万)のみ牛を有し番号1 ... N. 各牛の効率iは乳牛E_i(0 <= E_i <=10億)の効率で、異なっています。

牛は非常に精通閉じ、これだけ連続牛Kファームジョンの手配を超える場合には、牛がストライクパーティーに行きます:)。だから今ファームジョンは、最大効率が得られることを計算し、プログラムが連続Kの牛を超えていないあなたの助けFJを必要としています。

入力形式

最初のライン:スペースで区切られた二つの整数NとK

第N + 1行目:最初の行は、I + 1の整数E_iを有します

出力フォーマット

最初のライン:最大効率値を表す値は、ファームジョンを得ることができます。

サンプル入力と出力

入力#1

5 2
1
2
3
4
5

出力#1

12

[思考]

DPキューリニアモノトーン

の前に[話します]

非常に興味深い質問
、それのためにあることは、ほとんどの変数との間隔サイズを選択することです
ので、トラブルの多くは、右の
右の質問ヘッドをしたいですか?

[プレフィックス]アイデア

その後、来ないというの反対!
牛は多くの問題を見つけるために選択することができ
、その後牛識別するために選択していない
牛を選択していないが、小さくなければならない
とされていない他の範囲として、また
二つの連続選ば牛がより良い結果をすることはありませんではないがあるため
のみ結果は、悪化させる
複数の選択オプション未満が良いだろうので、
具体的な証拠を言っているのではない
ようなものを、次の自分の感情的な理解

[思考]ファイナル

次に列挙するために最初のポイントから開始する
チームを
そのチームは、この距離は最初のチームがポップアップしまうのk + 1よりも大きい指すように最初のものであるならば
、なぜ、それは+ 1をkと
、それが選択されていないので、牛
最長の連続区間があります長さkは、の
範囲となる牛の両側に選択されていない
この場合、距離k + 1であり
、これは最長の場合である
が、K + 1よりも大きく、
かつため最小のものを選択する
ことがキューテールよりも大きいですまた、ポップアップ表示さF [i]が
あるため発生しなかったチームの最後尾よりも小さい値の
私よりも私より少し強いです!

[注]

キューの先頭を超えた値の第1の範囲をポップ
し、次いでFを処理[I]の値である
吐出力の終端
[i]が最小法的前部の値に依存fと
違法最初のセクションに爆弾アウト
または[i]の合法的なfを保証することはできません
し、比較の基準をポップをf [i]はサイズである
最初のポップアップチームので、プロセスの終了前に[i]が値fを
、このような順序が轟音を出てきました

[完了コード】

#include<iostream>
#include<cstdio>
#include<queue>
#define int long long
using namespace std;
const int Max = 100005;
struct node
{
    int t;
    int v;
};
deque<node>q;
int a[Max];
int f[Max];
signed main()
{
    int n,k;
    cin >> n >> k;
    int tot = 0;
    for(register int i = 1;i <= n;++ i)
        cin >> a[i],tot += a[i];
    int M = 0x7f7f7f7f7f7f;
    q.push_back((node){0,0});
    for(register int i = 1;i <= n;++ i)
    {
        while(!q.empty() && i - q.front().t > k + 1)
            q.pop_front();
        f[i] = q.front().v + a[i];
        while(!q.empty() && f[i] < q.back().v)
            q.pop_back();
        q.push_back((node){i,f[i]});
    }
    for(register int i = n;i >= n - k;i --)
        M = min(M,f[i]);
    cout << tot - M << endl;
    return 0;
}

おすすめ

転載: www.cnblogs.com/acioi/p/11680772.html