因为 N < 40 所以这道题即使多维也不会MLE和TLE
设dp[i1][i2][i3][i4] 是使用了i1张1,i2张2,i3张3,i4张4后能得到的最大分数
需要注意dp[0][0][0][0]要设置为第一个格子的分数,不然会错
下面的代码中因为i1 i2 i3 i4一开始都是0 所以x+=t可以初始化dp[0][0][0][0]为第一个格子的分数
#include <cstdio>
#include <algorithm>
int n, m, m1, m2, m3, m4, a[360], b[130], dp[41][41][41][41];
inline void read(int &x) {
x = 0;
char c = getchar();
while(c<'0'||c>'9') c = getchar();
while(c>='0'&&c<='9') x = x*10 + c -'0', c = getchar();
return;
}
int main() {
read(n);
read(m);
for(int i=1; i<=n; i++)
read(a[i]);
for(int i=1; i<=m; i++){
read(b[i]);
if(b[i] == 1)
m1++;
else if(b[i] == 2)
m2++;
else if(b[i] == 3)
m3++;
else if(b[i] == 4)
m4++;
}
for(int i1=0; i1<=m1; i1++) {
for(int i2=0; i2<=m2; i2++) {
for(int i3=0; i3<=m3; i3++) {
for(int i4=0; i4<=m4; i4++) {
int &x = dp[i1][i2][i3][i4];//使用引用可以少打点字
int t = a[1+i1+2*i2+3*i3+4*i4];
if(i1 > 0)
x = std::max(x, dp[i1-1][i2][i3][i4]);
if(i2 > 0)
x = std::max(x, dp[i1][i2-1][i3][i4]);
if(i3 > 0)
x = std::max(x, dp[i1][i2][i3-1][i4]);
if(i4 > 0)
x = std::max(x, dp[i1][i2][i3][i4-1]);
x += t;
}
}
}
}
printf("%d",dp[m1][m2][m3][m4]);
return 0;
}

本文介绍了一种解决特定背包问题的方法,通过四维动态规划算法来求解最大分数。利用dp[i1][i2][i3][i4]表示使用不同数量的卡片后能达到的最大分数,并给出了完整的C++实现代码。
489

被折叠的 条评论
为什么被折叠?



