【SSL 1993】乌龟棋(多维DP)

题目大意

      小明过生日的时候,爸爸送给他一副乌龟棋当作礼物。
       乌龟棋的棋盘是一行 N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
       乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有 1,2,3,4 四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。
       游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
      很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
      现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?

输入格式

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

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

第2行N个非负整数,a1,a2,…,aN,其中ai表示棋盘第 i个格子上的分数。

第3行M个整数,b1,b2,…,bM,表示M张爬行卡片上的数字。

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

输出格式

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

输入样例

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

输出样例

73

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

基本思路

这题实现起来并不难,只不过用四维真的有些罕见。

这四位自然是1~4类型卡片使用数量了。

核心代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=400;
const int M=130;
int n,m,a[N],b[6],f[M][M][M][M];
//f[i][j][p][q]为i张1类卡片,j张2类卡片,p张3类卡片
//q张4类卡片
int main(){
	ios::sync_with_stdio(false);
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>a[i];
	for(int i=1;i<=m;i++){
		int bi;
		cin>>bi;
		b[bi]++;
	}
	f[0][0][0][0]=a[1];
	//我为人人:当前每张卡片数量
	for(int i=0;i<=b[1];i++)
		for(int j=0;j<=b[2];j++)
			for(int p=0;p<=b[3];p++)
				for(int q=0;q<=b[4];q++){
					int x=i+j*2+p*3+q*4+1;
					f[i+1][j][p][q]=max(f[i+1][j][p][q],f[i][j][p][q]+a[x+1]);
					f[i][j+1][p][q]=max(f[i][j+1][p][q],f[i][j][p][q]+a[x+2]);
					f[i][j][p+1][q]=max(f[i][j][p+1][q],f[i][j][p][q]+a[x+3]);
					f[i][j][p][q+1]=max(f[i][j][p][q+1],f[i][j][p][q]+a[x+4]);
				}
	cout<<f[b[1]][b[2]][b[3]][b[4]];
	return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值