動的プログラミング - キャンディ

世界平和の維持に対する彼の多大な貢献により、Dzx には 2010 年 5 月 23 日にキャンディー会社からキャンディーの無制限の無料クーポンが与えられました。

この日、Dzx はキャンディー会社からN個の製品を好きなだけ選び、家に持ち帰って楽しむことができます。

キャンディー会社のN製品には、それぞれ異なる数のキャンディーが含まれています。

Dzxは、世界平和の維持に協力してくれるパートナーにキャンディーを均等に分配できるように、自分が選択した製品に含まれるキャンディーの総数がKの整数倍であることを望んでいます。

もちろん、この条件を満たした上で、キャンディーは多ければ多いほど良いです。

Dzx は最大でどれくらいのキャンディーを持ち帰ることができますか?

注: Dzx は、キャンディー会社の製品全体のみを持ち帰ることができます。

入力フォーマット

最初の行には 2 つの整数NKが含まれています。

次のN行には、キャンディー会社の製品に含まれるキャンディーの数を示す整数が含まれます ( 1,000,000 を超えない)

出力フォーマット

条件を満たすキャンディーの最大数に達することができます。K の倍数の条件を満たせない場合は 0出力します。

データ範囲

1≦N≦100

1≤K≤100

入力サンプル:

5 7
1
2
3
4
5

出力例:

14

サンプル説明

Dzx の選択肢は 2+3+4+5=14 なので、キャンディーの合計数は 7 の倍数となり、合計数が最も多い選択肢になります。

アイデア: dp[i][j] は最初の i 項目から選択されたすべてのスキームを表し、合計を k で割った余りが j です。

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
#define N 110
int dp[N][N];
int main()
{
    memset(dp, -0x3f, sizeof(dp));
    dp[0][0] = 0;
    int n, k;
    cin >> n >> k;
    for (int i = 1; i <= n; i++)
    {
        int w;
        cin >> w;
        for (int j = 0; j < k; j++)
        {
            dp[i][j] = max(dp[i - 1][j], dp[i - 1][(j + k - w % k) % k] + w);
        }
    }
    cout << dp[n][0] << endl;
    return 0;
}

おすすめ

転載: blog.csdn.net/m0_73648729/article/details/129249311