算法知识点: 线性DP

复杂度:

解题思路:

状态表示: 表示所有第 种卡片使用了 张的走法的最大分值。

状态计算:将 表示的所有走法按最后一步选择哪张卡片分成四类:第 类为最后一步选择第 种卡片。比如 ,则这一类的最大分值是

C++ 代码:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std; const int N = 360,
    M = 41;

int n, m;
int score[N];
int f[M][M][M][M];

int main()
{
    int b[5] = { 0 };
    scanf("%d%d", &n, &m);
    for (int i = 0; i < n; i++) scanf("%d", &score[i]);

    for (int i = 0; i < m; i++)
    {
        int t;
        scanf("%d", &t);
        b[t]++;
    }

    for (int A = 0; A <= b[1]; A++)
        for (int B = 0; B <= b[2]; B++)
            for (int C = 0; C <= b[3]; C++)
                for (int D = 0; D <= b[4]; D++)
                {
                    int t = score[A + B * 2 + C * 3 + D * 4];
                    int &v = f[A][B][C][D];
                    v = t;
                    if (A) v = max(v, f[A - 1][B][C][D] + t);
                    if (B) v = max(v, f[A][B - 1][C][D] + t);
                    if (C) v = max(v, f[A][B][C - 1][D] + t);
                    if (D) v = max(v, f[A][B][C][D - 1] + t);
                }

    printf("%d\n", f[b[1]][b[2]][b[3]][b[4]]);
    return 0;
}


另外,牛客暑期NOIP真题班限时免费报名
报名链接:https://www.nowcoder.com/courses/cover/live/248
报名优惠券:DCYxdCJ