P1541 [NOIP2010 提高组] 乌龟棋
状态表示:
\(f(i,a,b,c,d)\):到达第\(i\)个格子,所用卡片\(1\)数量为\(a\)张,卡片\(2\)数量为\(b\)张,卡片\(3\)数量为\(c\)张,卡片\(4\)数量为\(d\)张时能够获得的分数最大值。
状态转移:
\[f(i,a,b,c,d)=\max
\begin{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
\begin{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;
}