A la carte problem: dynamic programming (C language implementation)

Table of contents

1. Topic overview:

2. Topic analysis:

 3. Title code:

4. Sample display:

5. Topic summary: 


1. Topic overview:

        A certain laboratory often needs to order takeout for activities, but the total amount of expenses reimbursed each time is up to C yuan, and there are N kinds of dishes that can be ordered. After a long time of ordering, the laboratory has a quantified amount for each dish i Score Vi, the price of this dish is Pi, ask how to choose various dishes (each dish can only be ordered once), so as to maximize the total evaluation score of the ordered dish within the reimbursement amount.

2. Topic analysis:

Similar to 0/1 backpack, each dish can only be selected or not selected, and can only be selected once at most.
Use dp[i][j] to represent the maximum score when the amount of the previous i dish is j, then dp[C][j ] is the answer, initialize all 0

Since each dish can only be selected once at most, in order to avoid double counting of a certain dish, it is necessary to circulate the dishes in the outer layer corresponding
to each dish. If
the added dp[j]
is higher than the original score, it will be added and updated, otherwise it will not be added and keep the original state,
so the transfer equation is obtained

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

Since each dish is only cycled once,
each dish will not be repeated, and each eligible price will be selected whether to join or not, so each price is the current optimal solution, and the global optimal solution will be obtained after the cycle .

Similar to the 0/1 knapsack problem, it can be expressed more clearly through the table: 

 3. Title code:

#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. Sample display:

 

5. Topic summary: 

        The difficulty of this experiment lies in the solution of the dynamic programming recursive formula and the construction of the dynamic programming table. At the same time, I think the definition, application and value transfer of two-dimensional arrays are also a major difficulty in this experiment. To sum up, in the design of algorithm problems, the key to the problem is to use recursion, construct a dynamic programming table, and continuously obtain the optimal value. Here is a brief analysis of the problem.

Guess you like

Origin blog.csdn.net/qq_58773908/article/details/127294196