状态表示:
(f(i,a,b,c,d)):到达第(i)个格子,所用卡片(1)数量为(a)张,卡片(2)数量为(b)张,卡片(3)数量为(c)张,卡片(4)数量为(d)张时能够获得的分数最大值。
状态转移:
[f(i,a,b,c,d)=max
egin{cases}
f(i-1,a-1,b,c,d)
\
f(i-2,a,b-1,c,d)
\
f(i-3,a,b,c-1,d)
\
f(i-4,a,b,c,d-1)
end{cases}
+w[i]
]
时间复杂度为:(O(n*40^4))。
考虑优化,可以发现(i=a*1+b*2+c*3+d*4+1),于是(i)这一维可优化掉。
[f(a,b,c,d)=max
egin{cases}
f(a-1,b,c,d)
\
f(a,b-1,c,d)
\
f(a,b,c-1,d)
\
f(a,b,c,d-1)
end{cases}
+w[a*1+b*2+c*3+d*4+1]
]
边界:
[f(0,0,0,0)=w[1]
]
const int N=355,M=45;
int w[N];
int f[M][M][M][M];
int cnt[5];
int n,m;
int main()
{
cin >> n >> m;
for (int i = 1; i <= n; i++)
cin >> w[i];
for (int i = 1; i <= m; i++)
{
int x;
cin >> x;
cnt[x]++;
}
f[0][0][0][0] = a[1];
for (int i = 0; i <= cnt[1]; i++)
for (int j = 0; j <= cnt[2]; j++)
for (int k = 0; k <= cnt[3]; k++)
for (int l = 0; l <= cnt[4]; l++)
{
int idx = i * 1 + j * 2 + k * 3 + l * 4 + 1;
int &v = f[i][j][k][l];
if (i) v = max(v, f[i-1][j][k][l] + w[idx]);
if (j) v = max(v, f[i][j-1][k][l] + w[idx]);
if (k) v = max(v, f[i][j][k-1][l] + w[idx]);
if (l) v = max(v, f[i][j][k][l-1] + w[idx]);
}
cout << f[cnt[1]][cnt[2]][cnt[3]][cnt[4]] << endl;
//system("pause");
return 0;
}