【动态规划】P1541 乌龟棋

https://www.luogu.com.cn/problem/P1541

P1541 乌龟棋【NOIp提高组2010】【普及+/提高】 题解

这是一道dp题目。关于dp题,在设计状态的时候,要想清楚在整个状态空间中发生变化的量有哪些。

对于这个题目,我们可以找到以下的“变量”:

1.棋子所在的位置;

2.所用的各个种类的牌的数量。(实际上算4个变量)

于是我们很容易想到使用五维数组 f [ i ][ a ][ b ][ c ][ d ] 来表示:走到第 i 个格子,用了标有数字 1~4 的卡牌分别有 a,b,c,d 张,所得到的最大分数。

我们还可以继续优化。很明显,如果a,b,c,d都知道的话,i 是可以推出来的,即1+a+2b+3c+4d(由于本来棋子就在第1格,所以要加1)。这时 i 叫做“冗余状态",可以省去,用 f [ a ][ b ][ c ][ d ] 表示用了标有数字 1~4 的卡牌分别有 a,b,c,d 张,能得到的最大分数。

状态转移:由于f [ a ][ b ][ c ][ d ]可以由f [ a-1 ][ b ][ c ][ d ],f [ a ][ b-1 ][ c ][ d ],f [ a ][ b ][ c-1 ][ d ]和f [ a ][ b ][ c ][ d-1 ]转移而来,再加上 k [ 1+a+2b+3c+4d ]即可。其中 k [ i ] 表示第 i 个格子的分数。上述所有条件取一个最大值即可。注意 a,b,c,d 均不能超过题目中所给的每种卡牌对应的数量。

初始状态:f [ 0 ][ 0 ][ 0 ][ 0 ] = k[ 1 ]。因为乌龟棋本来就在第一个格子上。

目标:f [ am ] [ b][ c][ d] 。其中 a表示 标有数字1的卡牌的数量,其他的以此类推。

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#define MAXN 1001
#define ll long long
#define re register
using namespace std;
int card[5];
inline int get_i(int a,int b,int c,int d)
{
    return 1+a+b*2+c*3+d*4;
}
int n,m;
int k[MAXN];
int f[41][41][41][41];
int main()
{
    ios::sync_with_stdio(false);
    cin>>n>>m;
    for(int i=1;i<=n;i++)
    {
        cin>>k[i];
    }
    int tmp;
    for(int i=1;i<=m;i++)
    {
        cin>>tmp;
        card[tmp]++;
    } 
    //dp
    f[0][0][0][0]=k[1];
    for(int a=0;a<=card[1];a++)
    {
        for(int b=0;b<=card[2];b++)
        {
            for(int c=0;c<=card[3];c++)
            {
                for(int d=0;d<=card[4];d++)
                {
                    int now=get_i(a,b,c,d);
                    if(a!=0) f[a][b][c][d]=max(f[a][b][c][d],f[a-1][b][c][d]+k[now]);
                    if(b!=0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b-1][c][d]+k[now]);
                    if(c!=0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c-1][d]+k[now]);
                    if(d!=0) f[a][b][c][d]=max(f[a][b][c][d],f[a][b][c][d-1]+k[now]);
                }
            }
        }
    }
    cout<<f[card[1]][card[2]][card[3]][card[4]]<<endl;
    return 0;
}

 

上一篇:41.在PyCharm中自动添加文件头、时间日期等信息


下一篇:41.函数应用:打印图形和数学计算