ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【动态规划】P1541 乌龟棋

2020-06-06 17:58:49  阅读:249  来源: 互联网

标签:tmp include int 卡牌 41 P1541 乌龟 动态 dp


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;
}

 

标签:tmp,include,int,卡牌,41,P1541,乌龟,动态,dp
来源: https://www.cnblogs.com/jiangyuechen/p/13055604.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有