题面
【题目描述】
小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
乌龟棋的棋盘是一行
N
N
N个格子,每个格子上一个分数(非负整数)。棋盘第
1
1
1格是唯一 的起点,第
N
N
N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
乌龟棋中M张爬行卡片,分成
4
4
4种不同的类型(M张卡片中不一定包含所有4种类型 的卡片,见样例),每种类型的卡片上分别标有
1
、
2
、
3
、
4
1、2、3、4
1、2、3、4四个数字之一,表示使用这种卡 片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择 一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。 游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到 该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的 分数总和。 很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡 片使用顺序使得最终游戏得分最多。 现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到 多少分吗?
【输入】
输入的每行中两个数之间用一个空格隔开。
第
1
1
1行
2
2
2个正整数
N
N
N和
M
M
M,分别表示棋盘格子数和爬行卡片数。
第
2
2
2行
N
N
N个非负整数,
a
1
,
a
2
…
…
a
N
a_1,a_2 …… a_N
a1,a2……aN,其中
a
i
a_i
ai表示棋盘第
i
i
i个格子上的分数。
第
3
3
3行
M
M
M个整数,
b
1
,
b
2
,
…
…
,
b
M
b_1,b_2,……,b_M
b1,b2,……,bM,表示M张爬行卡片上的数字。 输入数据保证到达终点时刚好用光
M
M
M张爬行卡片
【输出】
【样例输入】
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
【样例输出】
73
【数据范围】
说明/提示
小明使用爬行卡片顺序为
1
,
1
,
3
,
1
,
2
1,1,3,1,2
1,1,3,1,2,得到的分数为
6
+
10
+
14
+
8
+
18
+
17
=
73
6+10+14+8+18+17=73
6+10+14+8+18+17=73。注意,由于起点是
1
1
1,所以自动获得第
1
1
1格的分数
6
6
6。
对于
30
%
30\%
30%的数据有
1
≤
N
≤
30
,
1
≤
M
≤
12
1≤N≤30,1≤M≤12
1≤N≤30,1≤M≤12。
对于
50
%
50\%
50%的数据有
1
≤
N
≤
120
,
1
≤
M
≤
50
1≤N≤120,1≤M≤50
1≤N≤120,1≤M≤50,且
4
4
4种爬行卡片,每种卡片的张数不会超过
20
20
20。
对于
100
%
100 \%
100%的数据有
1
≤
N
≤
350
,
1
≤
M
≤
120
1≤N≤350,1≤M≤120
1≤N≤350,1≤M≤120,且
4
4
4种爬行卡片,每种卡片的张数不会超过
40
40
40;
0
≤
a
i
≤
100
,
1
≤
i
≤
N
,
1
≤
b
i
≤
4
,
1
≤
i
≤
M
0≤a_i≤100,1≤i≤N,1≤b_i≤4,1≤i≤M
0≤ai≤100,1≤i≤N,1≤bi≤4,1≤i≤M。
算法分析
四维DP。
为了表示乌龟其中走到当前的位置,设当前使用了
i
i
i张卡片
1
1
1,j张卡片
2
2
2,
k
k
k张卡片
3
3
3,
t
t
t张卡片
4
4
4。当前到达的格子数就是
s
=
1
+
i
+
2
∗
j
+
3
∗
k
+
4
∗
t
s=1+i+2 * j +3 * k+4 * t
s=1+i+2∗j+3∗k+4∗t,得到第
s
s
s格子的分数。
设状态:
f
[
i
]
[
j
]
[
k
]
[
t
]
f[i][j][k][t]
f[i][j][k][t]——表示使用了
i
i
i张卡片
1
1
1,
j
j
j张卡片
2
2
2,
k
k
k张卡片
3
3
3,
t
t
t张卡片
4
4
4得到的最高分数。
枚举使用的不同类型卡片的数量,找出最优解。
状态转移方程:
考虑到达当前位置时,使用的最后一张卡片类型:
最后使用的是卡片
1
:
f
[
i
]
[
j
]
[
k
]
[
t
]
=
m
a
x
(
f
[
i
]
[
j
]
[
k
]
[
t
]
,
f
[
i
−
1
]
[
j
]
[
k
]
[
t
]
+
s
c
o
r
e
[
s
]
)
;
1:f[i][j][k][t]=max(f[i][j][k][t],f[i-1][j][k][t]+score[s]);
1:f[i][j][k][t]=max(f[i][j][k][t],f[i−1][j][k][t]+score[s]);
最后使用的是卡片
2
:
f
[
i
]
[
j
]
[
k
]
[
t
]
=
m
a
x
(
f
[
i
]
[
j
]
[
k
]
[
t
]
,
f
[
i
]
[
j
−
1
]
[
k
]
[
t
]
+
s
c
o
r
e
[
s
]
)
;
2:f[i][j][k][t]=max(f[i][j][k][t],f[i][j-1][k][t]+score[s]);
2:f[i][j][k][t]=max(f[i][j][k][t],f[i][j−1][k][t]+score[s]);
最后使用的是卡片
3
:
f
[
i
]
[
j
]
[
k
]
[
t
]
=
m
a
x
(
f
[
i
]
[
j
]
[
k
]
[
t
]
,
f
[
i
]
[
j
]
[
k
−
1
]
[
t
]
+
s
c
o
r
e
[
s
]
)
;
3:f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k-1][t]+score[s]);
3:f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k−1][t]+score[s]);
最后使用的是卡片
4
:
f
[
i
]
[
j
]
[
k
]
[
t
]
=
m
a
x
(
f
[
i
]
[
j
]
[
k
]
[
t
]
,
f
[
i
]
[
j
]
[
k
]
[
t
−
1
]
+
s
c
o
r
e
[
s
]
)
;
4:f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k][t-1]+score[s]);
4:f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k][t−1]+score[s]);
最后的答案就是
f
[
a
]
[
b
]
[
c
]
[
d
]
,
a
,
b
,
c
,
d
f[a][b][c][d],a,b,c,d
f[a][b][c][d],a,b,c,d分别表示卡片
1
,
2
,
3
,
4
1,2,3,4
1,2,3,4的总数。
时间复杂度:
O
(
4
0
4
)
O(40^4)
O(404)
参考程序
#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
int score[360],f[42][42][42][42];
int main(){
int n,m,x;
int a=0,b=0,c=0,d=0;
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>score[i];
for(int i=1;i<=m;i++)
{
cin>>x;
if(x==1) a++;
if(x==2) b++;
if(x==3) c++;
if(x==4) d++;
}
for(int i=0;i<=a;i++)
for(int j=0;j<=b;j++)
for(int k=0;k<=c;k++)
for(int t=0;t<=d;t++)
{
int s=i+j*2+k*3+t*4+1;
if(i) f[i][j][k][t]=max(f[i][j][k][t],f[i-1][j][k][t]+score[s]);
if(j) f[i][j][k][t]=max(f[i][j][k][t],f[i][j-1][k][t]+score[s]);
if(k) f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k-1][t]+score[s]);
if(t) f[i][j][k][t]=max(f[i][j][k][t],f[i][j][k][t-1]+score[s]);
}
cout<<f[a][b][c][d]+score[1];
return 0;
}