算法知识点: 线性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; }