1. 程式人生 > >[Noip2010]烏龜棋

[Noip2010]烏龜棋

2個 nbsp 告訴 pac 提示 表示 put 明顯 要求

小明過生日的時候,爸爸送給他一副烏龜棋當作禮物。烏龜棋的棋盤是一行N個格子,每個格子上一個分數(非負
整數)。棋盤第1格是唯一的起點,第N格是終點,遊戲要求玩家控制一個烏龜棋子從起點出發走到終點。

烏龜棋中M張爬行卡片,分成4種不同的類型(M張卡片中不一定包含所有4種類型的卡片,見樣例),每種類型的卡
片上分別標有1、2、3、4四個數字之一,表示使用這種卡片後,烏龜棋子將向前爬行相應的格子數。遊戲中,玩家
每次需要從所有的爬行卡片中選擇一張之前沒有使用過的爬行卡片,控制烏龜棋子前進相應的格子數,每張卡片只
能使用一次。遊戲中,烏龜棋子自動獲得起點格子的分數,並且在後續的爬行中每到達一個格子,就得到該格子相
應的分數。玩家最終遊戲得分就是烏龜棋子從起點到終點過程中到過的所有格子的分數總和。很明顯,用不同的爬
行卡片使用順序會使得最終遊戲的得分不同,小明想要找到一種卡片使用順序使得最終遊戲得分最多。現在,告訴

你棋盤上每個格子的分數和所有的爬行卡片,你能告訴小明,他最多能得到多少分嗎?

Input

輸入文件的每行中兩個數之間用一個空格隔開。
第1行2個正整數N和M,分別表示棋盤格子數和爬行卡片數。
第2行N個非負整數,a1a2……aN,其中ai表示棋盤第i個格子上的分數。
第3行M個整數,b1b2……bM,表示M張爬行卡片上的數字。
輸入數據保證到達終點時剛好用光M張爬行卡片。

Output

輸出只有1行,1個整數,表示小明最多能得到的分數。
1≤N≤350,1≤M≤120,且4種爬行卡片,每種卡片的張數不會超過40
0≤ai≤100,1≤i≤N;1≤bi≤4,1≤i≤M。

Sample Input

3
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1

Sample Output

73
提示
小明使用爬行卡片順序為1,1,3,1,2,得到的分數為6+10+14+8+18+17=73。
註意,由於起點是1,所以自動獲得第1格的分數6。

這個題簡直就是暴力,反正四種棋,每個的數量記錄下來暴力枚舉一遍就可以了,這種dp也是夠奇怪了,我也是第一次寫就寫掛了,不懂為什麽寫二維的就會掛,唉,貼上這個四維dp的代碼吧。

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 int i,j,k,n,m,p,a[401],b,f[40][40][40][40
],sum[5]; 5 int main() 6 { 7 //freopen("chess.in","r",stdin); 8 //freopen("chess.out","w",stdout); 9 scanf("%d%d",&n,&m); 10 for(i=1;i<=n;i++) 11 scanf("%d",&a[i]); 12 for(i=1;i<=m;i++) 13 scanf("%d",&b),sum[b]++; 14 for(i=0;i<=sum[1];i++) 15 for(j=0;j<=sum[2];j++) 16 for(k=0;k<=sum[3];k++) 17 for(int t=0;t<=sum[4];t++) 18 f[i][j][k][t]=max(max(max(f[max(0,i-1)][j][k][t],f[i][max(0,j-1)][k][t]),f[i][j][max(0,k-1)][t]),f[i][j][k][max(0,t-1)])+a[1+i+2*j+3*k+4*t]; 19 printf("%d",f[sum[1]][sum[2]][sum[3]][sum[4]]); 20 }

[Noip2010]烏龜棋