题解:可以用f[a][b][c][d],已经使用了a张1类型卡片,b张2类型卡片,c张3类型卡片,d张4类型卡片,能获得的最大的分数。因为当前的位置可以用a,b,c,d确定,所以省掉一维数组
#include <iostream>
#include <cstdio>
using namespace std;
int n,m,s,a;
int value[400],w[5],x[5];
int f[40][40][40][40];
inline void init()
{
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++)
scanf("%d",&value[i]);//从0开始,因为abcd均为0时,应加上开始点的值value[0]
for(int i=1;i<=m;i++)
scanf("%d",&a),w[a]++;
}
inline void work()
{
for(int a=0;a<=w[1];a++)
for(int b=0;b<=w[2];b++)
for(int c=0;c<=w[3];c++)
for(int d=0;d<=w[4];d++)
{
s=f[a][b][c][d];//高维数组寻址优化
if(a) s=max(s,f[a-1][b][c][d]);
if(b) s=max(s,f[a][b-1][c][d]);
if(c) s=max(s,f[a][b][c-1][d]);
if(d) s=max(s,f[a][b][c][d-1]);
s+=value[a+b*2+c*3+d*4];//到达点的值
f[a][b][c][d]=s;
}
printf("%d\n",f[w[1]][w[2]][w[3]][w[4]]);
}
int main()
{
init();
work();
return 0;
}