Official

D - Poisonous Full-Course Editorial by en_translator


Consider solving this problem with a Dynamic Programming (DP). What store should we maintain?

Going straight to the point, the problem can be solved by filling the following DP table.

  • dp[dp[ course ii ][][ Takahashi’s state jj ]]
    • The maximum total tastiness of the courses that he has eaten when he has decided whether to eat or skip for the first ii courses and his state is jj (00 … he has an healthy stomach, 11 … he has an upset stomach.)

If you could not solve this problem, given “how the DP table can be defined” above, try implementing while considering “how the transitions should be.” It is a good exercise of DP.

Explanation of transitions

Copy
  1. // Note that 0-based indices are used for the courses in the sample code
  2. // Initialize the DP table
  3. for(long long i=0;i<=n;i++){
  4. dp[i][0]=-4e18; // dp[i][0] = -∞
  5. dp[i][1]=-4e18; // dp[i][1] = -∞
  6. }
  7. dp[0][0]=0; // Initially, he has a healthy stomach
  8. for(long long i=0;i<n;i++){
  9. // Transition for his choice of eating the i-th course
  10. if(x[i]==0){
  11. dp[i+1][0]=max(dp[i][0],max(dp[i][0],dp[i][1])+y[i]);
  12. }
  13. else{
  14. dp[i+1][1]=max(dp[i][1],dp[i][0]+y[i]);
  15. }
  16. // Transition for his choice of skipping the i-th course
  17. dp[i+1][0]=max(dp[i+1][0],dp[i][0]);
  18. dp[i+1][1]=max(dp[i+1][1],dp[i][1]);
  19. }
  // Note that 0-based indices are used for the courses in the sample code
  // Initialize the DP table
  for(long long i=0;i<=n;i++){
    dp[i][0]=-4e18; // dp[i][0] = -∞
    dp[i][1]=-4e18; // dp[i][1] = -∞
  }
  dp[0][0]=0; // Initially, he has a healthy stomach

  for(long long i=0;i<n;i++){
    // Transition for his choice of eating the i-th course
    if(x[i]==0){
      dp[i+1][0]=max(dp[i][0],max(dp[i][0],dp[i][1])+y[i]);
    }
    else{
      dp[i+1][1]=max(dp[i][1],dp[i][0]+y[i]);
    }
    // Transition for his choice of skipping the i-th course
    dp[i+1][0]=max(dp[i+1][0],dp[i][0]);
    dp[i+1][1]=max(dp[i+1][1],dp[i][1]);
  }


Sample code (C++):

Copy
  1. #include<bits/stdc++.h>
  2. using namespace std;
  3. long long dp[300005][2];
  4. int main(){
  5. long long n;
  6. cin >> n;
  7. vector<long long> x(n),y(n);
  8. for(long long i=0;i<n;i++){
  9. cin >> x[i] >> y[i];
  10. }
  11. for(long long i=0;i<=n;i++){
  12. dp[i][0]=-4e18;
  13. dp[i][1]=-4e18;
  14. }
  15. dp[0][0]=0;
  16. for(long long i=0;i<n;i++){
  17. if(x[i]==0){
  18. dp[i+1][0]=max(dp[i][0],max(dp[i][0],dp[i][1])+y[i]);
  19. }
  20. else{
  21. dp[i+1][1]=max(dp[i][1],dp[i][0]+y[i]);
  22. }
  23. dp[i+1][0]=max(dp[i+1][0],dp[i][0]);
  24. dp[i+1][1]=max(dp[i+1][1],dp[i][1]);
  25. }
  26. cout << max(dp[n][0],dp[n][1]) << "\n";
  27. return 0;
  28. }
#include<bits/stdc++.h>

using namespace std;

long long dp[300005][2];

int main(){
  long long n;
  cin >> n;
  vector<long long> x(n),y(n);
  for(long long i=0;i<n;i++){
    cin >> x[i] >> y[i];
  }

  for(long long i=0;i<=n;i++){
    dp[i][0]=-4e18;
    dp[i][1]=-4e18;
  }
  dp[0][0]=0;

  for(long long i=0;i<n;i++){
    if(x[i]==0){
      dp[i+1][0]=max(dp[i][0],max(dp[i][0],dp[i][1])+y[i]);
    }
    else{
      dp[i+1][1]=max(dp[i][1],dp[i][0]+y[i]);
    }

    dp[i+1][0]=max(dp[i+1][0],dp[i][0]);
    dp[i+1][1]=max(dp[i+1][1],dp[i][1]);
  }
  cout << max(dp[n][0],dp[n][1]) << "\n";
  return 0;
}

posted:
last update:



2025-04-08 (Tue)
20:30:57 +00:00