zoukankan      html  css  js  c++  java
  • P1541 乌龟棋 线性dp

    题目背景

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

    题目描述

    乌龟棋的棋盘是一行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≤121N30,1M12。

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

    对于100\%100%的数据有1≤N≤350,1≤M≤1201N350,1M120,且44种爬行卡片,每种卡片的张数不会超过4040;0≤a_i≤100,1≤i≤N,1≤b_i≤4,1≤i≤M0ai100,1iN,1bi4,1iM。

    本来写了五维

    但是第一维i是没有必要的   因为所走的距离可以用这四种牌算出来

    然后就是枚举所有牌的情况就可以了

    #include<bits/stdc++.h>
    using namespace std;
    //input by bxd
    #define rep(i,a,b) for(int i=(a);i<=(b);i++)
    #define repp(i,a,b) for(int i=(a);i>=(b);i--)
    #define RI(n) scanf("%d",&(n))
    #define RII(n,m) scanf("%d%d",&n,&m)
    #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k)
    #define RS(s) scanf("%s",s);
    #define LL long long
    #define pb push_back
    #define fi first
    #define REP(i,N)  for(int i=0;i<(N);i++)
    #define CLR(A,v)  memset(A,v,sizeof A)
    ///////////////////////////////////
    #define inf 0x3f3f3f3f
    #define N 350+5
    int dp[41][41][41][41];
    int aa[N];
    int sum[5];
    int main()
    {
       int n,m;
       RII(n,m);
       rep(i,1,n)
       RI(aa[i]);
       rep(i,1,m)
       {
           int x;
           RI(x);
           sum[x]++;
       }
       dp[0][0][0][0]=aa[1];
       rep(a,0,sum[1])
       rep(b,0,sum[2])
       rep(c,0,sum[3])
       rep(d,0,sum[4])
       {
           int x=1+a+2*b+3*c+4*d;
           if(a)dp[a][b][c][d]=max(dp[a-1][b][c][d]+aa[x],dp[a][b][c][d]);
           if(b)dp[a][b][c][d]=max(dp[a][b-1][c][d]+aa[x],dp[a][b][c][d]);
           if(c)dp[a][b][c][d]=max(dp[a][b][c-1][d]+aa[x],dp[a][b][c][d]);
           if(d)dp[a][b][c][d]=max(dp[a][b][c][d-1]+aa[x],dp[a][b][c][d]);
       }
        cout<<dp[sum[1]][sum[2]][sum[3]][sum[4]];
        return 0;
    }
    View Code
  • 相关阅读:
    设计模式——观察者模式
    LeetCode OJ——Word Ladder
    unorder_set<typename T> 学习
    LeetCode OJ——Text Justification
    LeetCode OJ——Two Sum
    LeetCode OJ——Longest Valid Parentheses
    路飞学城Python-Day16
    路飞学城Python-Day15
    路飞学城Python-Day14(practise)
    路飞学城Python-Day14
  • 原文地址:https://www.cnblogs.com/bxd123/p/10611167.html
Copyright © 2011-2022 走看看