アラカルト問題:動的プログラミング(C言語実装)

目次

1. トピックの概要:

2. トピック分析:

 3. タイトルコード:

4. サンプル表示:

5. トピックの概要: 


1. トピックの概要:

        ある研究室では活動のためにテイクアウトを頻繁に注文する必要があるが、毎回の精算額はC元までで、注文できる料理の種類はN種類で、長時間注文した結果、研究室は定量化された各料理の金額 i スコア Vi、この料理の価格を Pi として、償還金額内で注文した料理の合計評価点が最大になるようにさまざまな料理 (各料理は 1 回のみ注文可能) を選択する方法を尋ねます。

2. トピック分析:

0/1 バックパックと同様に、各料理は選択または非選択のみで、最大 1 回しか選択できません。
前の i 皿の量が j のときの最大スコアを dp[i][j] で表します。 dp[C][j ] が答えなので、すべて 0 を初期化します。


各料理は最大で 1 回しか選択できないため、特定の料理の二重カウントを避けるためには、各料理に
対応する
外層の料理を循環させる必要があります。スコアの場合は追加されて更新され、それ以外の場合は追加されずに元の状態が維持されるため、
伝達方程式が得られます。

dp[i][j] = max( dp[i-1][j] , dp[i-1][jp[i]] + v[i])

各料理は 1 回だけ循環されるため、
各料理は繰り返されず、参加するかどうかの対象となる各価格が選択されるため、各価格が現在の最適解となり、サイクル後に全体的な最適解が得られます。

0/1 ナップザック問題と同様に、次の表を使用してより明確に表現できます。 

 3. タイトルコード:

#include <stdio.h>
#include <math.h>
int max(int a, int b)
{
    if (a > b)
        return a;
    else
        return b;
}
int main()
{
    int n, C, i, j, k = 0;
    int temp;
    printf("请输入菜的种类个数:");
    scanf("%d", &n);
    printf("请输入外卖报销最大的经费数额:");
    scanf("%d", &C);
    int Vi[n], Pi[n], MaxValue[C + 1][n + 1], a[n];
    printf("请输入每种菜的量化评分:");
    for (i = 0; i < n; i++)
        scanf("%d", &Vi[i]);
    printf("请输入与之对应的每种菜的价格:");
    for (i = 0; i < n; i++)
        scanf("%d", &Pi[i]);
    for (i = 0; i < C + 1; i++)
        MaxValue[i][0] = 0;
    for (i = 0; i < n + 1; i++)
        MaxValue[0][i] = 0;
    for (j = 1; j <= n; j++)
    {
        for (i = 1; i <= C; i++)
        {
            if (Pi[j - 1] > i)
                MaxValue[i][j] = MaxValue[j - 1][i];
            else
                MaxValue[i][j] = max(MaxValue[i - Pi[j - 1]][j - 1] + Vi[j - 1], MaxValue[i][j - 1]);
        }
        if (MaxValue[i - 1][j] != MaxValue[i - 1][j - 1])
        {
            a[k] = j;
            k++;
        }
    }
    printf("选择的菜的种类为: ");
    for (i = 0; i < k; i++)
    {
        printf("第%d种 ", a[i]);
    }
    printf("\n");
    printf("点到菜的总评价分数为: %d\n", MaxValue[C][n]);
    return 0;
}

4. サンプル表示:

 

5. トピックの概要: 

        この実験の難しさは、動的計画法の再帰公式の解法と動的計画表の構築にあります。同時に、2次元配列の定義、適用、値の転送もこの実験の大きな難しさだと思います。要約すると、アルゴリズム問題の設計において、問題の鍵となるのは、再帰を使用し、動的計画表を構築し、最適な値を継続的に取得することです。ここで問題を簡単に分析します。

おすすめ

転載: blog.csdn.net/qq_58773908/article/details/127294196