秋祭 | 静岡高校工学部



卬高杯

G問題 - Drinking Iced Tea - 解説 by miromaru360

実行時間制限: 2 sec / メモリ制限: 1024 MB

この問題は、動的計画法(DP)を使うことで解くことができます。
具体的には、DPテーブル`dp[ i ][ w ]`をグラス`i`のアイスティーまで飲むかどうか決めたとき、睡眠薬を`w`㎎以下にできる最大のアイスティーの量とし、`dp[N][M-1]`が答えになります。
漸化式は、各`i`に対して

`dp[ i ][ w ] = \max(dp[i-1][w],dp[i-1][w-Y_i]+X_i)`


です。範囲外アクセスに注意してください。
計算量は`O(NM)`であり十分高速です。

余談ですが、この問題は0-1ナップザック問題と呼ばれるDPの典型問題です。AtCoderなどのコンテストでも頻出なので、覚えておいて損はないと思います。
解答例(C++)
#include<bits/stdc++.h>
using namespace std;
int main(){
    int N,M;
    cin >> N >> M;
    vector<int> X(N),Y(N);
    for(int i = 0;i < N;i++) cin >> X[i];
    for(int i = 0;i < N;i++) cin >> Y[i];
    vector<vector<int>> dp(N+1,vector<int>(M,0));
    for(int i = 1;i <= N;i++){
        for(int j = 0;j < M;j++){
            if(j>=Y[i-1]) dp[i][j]=max(dp[i-1][j],dp[i-1][j-Y[i-1]]+X[i-1]);
            else dp[i][j]=dp[i-1][j];
        }
    }
    cout << dp[N][M-1] << endl;
}
問題はここから