ICode9

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

洛谷 P1541 乌龟棋

2021-12-06 20:34:08  阅读:166  来源: 互联网

标签:分数 洛谷 格子 卡片 int 爬行 P1541 乌龟


P1541 [NOIP2010 提高组] 乌龟棋

题目背景

小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。

题目描述

乌龟棋的棋盘是一行NN个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第NN格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。

乌龟棋中MM张爬行卡片,分成4种不同的类型(MM张卡片中不一定包含所有44种类型的卡片,见样例),每种类型的卡片上分别标有1,2,3,41,2,3,4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。

游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。

很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。

现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?

输入格式

每行中两个数之间用一个空格隔开。

第11行22个正整数N,MN,M,分别表示棋盘格子数和爬行卡片数。

第22行NN个非负整数,a_1,a_2,…,a_Na1​,a2​,…,aN​,其中a_iai​表示棋盘第ii个格子上的分数。

第33行MM个整数,b_1,b_2,…,b_Mb1​,b2​,…,bM​,表示M张爬行卡片上的数字。

输入数据保证到达终点时刚好用光MM张爬行卡片。

输出格式

11个整数,表示小明最多能得到的分数。

输入输出样例

输入 #1
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
输出 #1
73

说明/提示

每个测试点1s1s

小明使用爬行卡片顺序为1,1,3,1,21,1,3,1,2,得到的分数为6+10+14+8+18+17=736+10+14+8+18+17=73。注意,由于起点是11,所以自动获得第11格的分数66。

对于30\%30%的数据有1≤N≤30,1≤M≤121≤N≤30,1≤M≤12。

对于50\%50%的数据有1≤N≤120,1≤M≤501≤N≤120,1≤M≤50,且44种爬行卡片,每种卡片的张数不会超过2020。

对于100\%100%的数据有1≤N≤350,1≤M≤1201≤N≤350,1≤M≤120,且44种爬行卡片,每种卡片的张数不会超过4040;0≤a_i≤100,1≤i≤N,1≤b_i≤4,1≤i≤M0≤ai​≤100,1≤i≤N,1≤bi​≤4,1≤i≤M。

思路:

与蓝皮书上的照相排序类似,这里也是线性dp,状态表示有很多维~

首先想想这个题状态怎么表示,既然只有四种牌,并且每种牌不会超过40,可以开一个四维的数组来表示状态,具体表示为,每种牌已经使用的个数f(a,b,c,d)

想要找到的状态属性是最大值,所以每次状态转移时记得取个max

状态转移:将1,2,3,4其中一个牌用掉一张,并且获取在下一步将要获得的分数

假如用掉的是牌1,则f = max(f, f[a - 1][b][c][d] + score[...]) 这里f[a - 1][...]是上一个状态,也就是转移前的"未曾使用第一张牌"这个状态

题解:

/*
************************************
***********emu^w^***********
 
*/

#include <bits/stdc++.h>
using namespace std;
#define x first
#define y second
const int P = 13131;
#define ll long long
const int mod = 1E6 + 7;
const int INF = 0x3f, sINF = 0x3f3f3f3f;
typedef unsigned long long ULL;
typedef pair<int, int> PII;
typedef pair<long long, long long> PLL;
int dx[4] = {1, 0, -1, 0}, dy[4] = {0, 1, 0, -1};
//
const int N = 41;
int f[N][N][N][N];
int card[5], q[400];
int n, m;

int main()
{
    cin>>n>>m;
    for(int i = 0; i < n; i++) cin>>q[i];
    
    while(m--)
    {
        int temp;
        cin>>temp;
        card[temp]++;
    }
    
    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 temp = q[a + 2 * b + 3 * c + 4 * d];
                    int &v = f[a][b][c][d];
                    v = temp;
                    if(a) v = max(v, f[a - 1][b][c][d] + temp);
                    if(b) v = max(v, f[a][b - 1][c][d] + temp);
                    if(c) v = max(v, f[a][b][c - 1][d] + temp);
                    if(d) v = max(v, f[a][b][c][d - 1] + temp);
                }
                
        cout<<f[card[1]][card[2]][card[3]][card[4]];
}

时间复杂度O(40^4);

附带一张闫氏dp分析线性dp思维图

 

 

标签:分数,洛谷,格子,卡片,int,爬行,P1541,乌龟
来源: https://www.cnblogs.com/lviy/p/15651703.html

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

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

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

ICode9版权所有