刚开始题意都没有读懂,最近刚开始学dp,只知道机械的套用。硬生生地用背包的模板来考虑这个问题。
具体思路见代码:
AC代码
#include <bits/stdc++.h>
#define IN \
ios::sync_with_stdio(0); \
cin.tie(0);
using namespace std;
#define ll long long
const int N = 1e3 + 10;
int n, m, ans;
int a[355], cnt[5];
int f[41][41][41][41]; // f[a][b][c][d]四种卡片分别使用了a,b,c,d张
int main() {
cin >> m >> n;
int t;
cin >> t;
f[0][0][0][0] = t;
m--; // 第一个位置上的值已经获得
for (int i = 1; i <= m; i++) {
cin >> a[i];
}
int x;
for (int i = 1; i <= n; i++) {
cin >> x;
cnt[x]++;
}
// 要是这样写的话相对于完全确定了卡片的使用顺序,肯定是不行的
// 对dp还是掌握不熟练,包括对题意的理解也是不行的
// for (int i = 1; i <= n; i++) {
// for (int j = m - 1; j >= b[i]; j--) {
// if (f[i - 1][j - b[i]] != -1)
// f[i][j] = max(f[i - 1][j - b[i]] + a[j], f[i][j]);
// }
// }
// cout << f[n][m - 1] << endl;
for (int A = 0; A <= cnt[1]; A++)
for (int B = 0; B <= cnt[2]; B++)
for (int C = 0; C <= cnt[3]; C++)
for (int D = 0; D <= cnt[4]; D++) {
int t = A + B * 2 + C * 3 + D * 4;
if (A)
f[A][B][C][D] =
max(f[A][B][C][D], f[A - 1][B][C][D] + a[t]);
if (B)
f[A][B][C][D] =
max(f[A][B][C][D], f[A][B - 1][C][D] + a[t]);
if (C)
f[A][B][C][D] =
max(f[A][B][C][D], f[A][B][C - 1][D] + a[t]);
if (D)
f[A][B][C][D] =
max(f[A][B][C][D], f[A][B][C][D - 1] + a[t]);
}
// 恰好用完所有卡片
cout << f[cnt[1]][cnt[2]][cnt[3]][cnt[4]];
}