http://www.luogu.org/problem/show?pid=1541
设f[i][j][k][l]为四种卡片的使用次数,则不难得出状态转移方程
f[i,j,k,l]=max{[i-1,j,k,l],f[i,j-1,k,l],f[i,j,k-1,l],f[i,j,k,l-1]}+s[i*1+j*2+k*3+l*4];
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define ms(i,j) memset(i,j, sizeof i);
using namespace std;
int n,m;
int ai[352];
int c[10];
int f[45][45][45][45];
int main()
{
scanf("%d%d", &n, &m);
for (int i=1;i<=n;i++)
scanf("%d", &ai[i]);
ms(c,0);
for (int i=1;i<=m;i++)
{
int x;
scanf("%d", &x);
c[x]++;
}
ms(f,0);
for (int i=0;i<=c[1];i++)
for (int j=0;j<=c[2];j++)
for (int k=0;k<=c[3];k++)
for (int l=0;l<=c[4];l++)
{
if (i!=0) f[i][j][k][l] = max(f[i][j][k][l],f[i-1][j][k][l]);
if (j!=0) f[i][j][k][l] = max(f[i][j][k][l],f[i][j-1][k][l]);
if (k!=0) f[i][j][k][l] = max(f[i][j][k][l],f[i][j][k-1][l]);
if (l!=0) f[i][j][k][l] = max(f[i][j][k][l],f[i][j][k][l-1]);
f[i][j][k][l] += ai[i+2*j+3*k+4*l+1];
}
printf("%d\n", f[c[1]][c[2]][c[3]][c[4]]);
return 0;
}