【ルオグ】P1353【USACO08JAN】ランニングS(動的計画法)

タイトル説明

トピックリンク:P1353 [USACO08JAN]走っているS
牛は、運動を通じて自分の運動細胞を培養することを計画しています。その1つとして、ベッシーは毎日運動することを選択しますnnn-分の朝のジョギング。毎分の初めに、ベッシーは次の分をランニングと休憩のどちらに使用するかを選択します。
ベッシーの体力は彼女が走ることができる距離を制限します。より具体的には、ベッシーがiiに参加することを選択した場合i分で実行、彼女はこの分でdi d_ {i}を実行できますdメートル、そして彼女の倦怠感は1増加します。ただし、ベッシーの倦怠感はいつでもmmを超えることはできませんm
ベッシーが休むことを選択した場合、彼女の倦怠感は1分あたり1減少しますが、倦怠感が0に戻るまで休む必要があります。疲労レベル00で0時に休んでも倦怠感は変わりません。朝のジョギングの開始時、ベッシーの倦怠感は0でした。
また、n分間の運動の終わりに、ベッシーの倦怠感も0に戻らなければなりません。そうしないと、彼女はその日の残りの部分に対処するのに十分なエネルギーを得ることができません。
Bessieが最大で何メートル走れるかを計算してください。

入力フォーマット

最初の行の2つの正の整数nnnmmm
次のn行、各行は正の整数di d_ {i}です。d

出力フォーマット

すべての制限が満たされた場合にBessieが実行できる最大距離を表す整数を出力します。

入力と出力の例:
入力

5 2
5
3
4
2
10

出力

9

説明/ヒント
[データ範囲]
のために100%100 \%1 0 0 データの1≤N≤1 0 41≤n≤10^ 41n1 04 1≤ジ≤千1≤d_{I}≤10001d1 0 0 0 1≤M≤5001≤m≤5001m5 0 0
【説明例】
ベッシーは11に1分以内に実行することを選択します(5 5を実行)5メートル)、2番目の2で2分以内に3日3日休憩3分以内に実行(実行4 44メートル)、残りの時間は休憩に費やされます。
朝のジョギングの終わりには、ベッシーの倦怠感は00でなければならないからです0なので、彼女は5番目と5番目に入ることができません5分以内に実行することを選択します。
最終走行での総距離は999

問題解決のアイデア:

  • 定義dp [i] [j]は、i分で実行できる最大距離を表し、疲労度はjです。
  • ポジティブシンキングは、i分で倦怠感がjの場合、休むか歩き続けるかの2つの選択肢があることを示しています。(1)休むことを選択した場合は、疲労度がゼロになるまで休む必要があります。安静時、倦怠感は1分ごとに1ずつ減少します。倦怠感がjの場合、j分間休む必要があるため、次の状態はdp [i + j] [0]です。静止中は距離は増加しません。つまり、dp [i + j] [0]はdp [i] [j]と等しくなります。(2)i分で歩くと、倦怠感が1増加し、距離がd [i]増加し、時間が1分長くなります。したがって、次の状態はdp [i + 1] [j +1]です。そして、dp [i + 1] [j + 1] = dp [i] [j] + d [i]。
  • 特定の状態を再帰的に実行するときは、関連するすべての「前の状態」を知る必要があるため、再帰に使用できる状態遷移方程式を確認するために、考え方を逆にする必要があります。
  • dp [i] [j]がどの「前の状態」に移行できるかを逆に考えてみましょう。(1)倦怠感が0になるまで休息する必要があるため、倦怠感jをj分間連続して蓄積する必要があります。 i番目の微小疲労度がjの状態は、「i-1分の疲労度がj-1」の状態から取得し、d [i]に進む必要があります。そのj≠0j \ neq0j=0では、dp [i] [j]の前の状態はdp [i-1] [j-1]であり、dp [i] [j] = dp [i-1] [j-1] + dを満たします。 [私]。(2)残りの疲労度は0です。疲労度がjの状態でj分間休むと、疲労度は0になります。つまり、「i分目の倦怠感は0」は「ij分目の休息j」によって得られるので、jの値は[1、i]の任意の値になり、倦怠感は0であるため、休むことができるので、「i番目の-1分の倦怠感は0です」を最後の状態として使用することもできます。最も遠い距離を見つけるには、最大値の1つを取るだけで済みます。
  • 最终的利态変換移方程修正:{j = 0:dp [i] [0] = max(dp [i-1] [0]、dp [ij] [j])(j∈[1、i])j ≠0dp [i] [j] = dp [i-1] [j-1] + d [i] \ begin {cases} j = 0:&\ text {dp [i] [0] = max(dp [i-1] [0]、dp [ij] [j])(j $ \ in $ [1、i])} \\ j \ neq0&\ text {dp [i] [j] = dp [i- 1] [j-1] + d [i]} \ end {cases}{{ j=0j=0dp [i] [0] = max(dp [i-1] [0]、dp [ij] [j])(j [1、i])DP [I] [J] = DP [I-1] [J-1] + D [i]は

ACコード:

#include<iostream>
#include<cstdio>
    using namespace std;
    const int N=1e4+100,M=5e2+100;
    int d[N],dp[N][M];
    int main(){
    
    
     //freopen("P1353_2.in.txt","r",stdin);
     //freopen("P1353_2.out.txt","w",stdout);
      int n,m;
      cin>>n>>m;
      for(int i=1;i<=n;i++){
    
    
      cin>>d[i];
      }
    for(int i=1;i<=n;i++){
    
    
        dp[i][0]=dp[i-1][0];
        for(int j=1;j<=i;j++){
    
    dp[i][0]=max(dp[i][0],dp[i-j][j]);}
        for(int j=1;j<=m;j++) dp[i][j]=dp[i-1][j-1]+d[i];
           }
     cout<<dp[n][0]<<endl;
    // fclose(stdin);
    // fclose(stdout);
     return 0;
                 }



前のブログ:[Luogu] [NOIP2014改善されたグループ]ジョイントウェイト(bfs + Picture)

おすすめ

転載: blog.csdn.net/IAMLSL/article/details/114816513