1. 程式人生 > >P1541 烏龜棋 線性dp

P1541 烏龜棋 線性dp

個數 距離 -o rep 但是 類型 push_back 遊戲 順序

題目背景

小明過生日的時候,爸爸送給他一副烏龜棋當作禮物。

題目描述

烏龜棋的棋盤是一行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≤M0ai?100,1iN,1bi?4,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

P1541 烏龜棋 線性dp