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;
}
posted @ 2021-05-16 16:24  Dazzling!  阅读(70)  评论(0编辑  收藏  举报