洛谷P1541 乌龟棋(四维DP)


To 洛谷.1541 乌龟棋

题目背景

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

题目描述

乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。

乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1、2、3、4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数。游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。

游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。

很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。

现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?

输入输出格式

输入格式:

输入文件的每行中两个数之间用一个空格隔开。

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

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

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

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

输出格式:

输出只有1行,1个整数,表示小明最多能得到的分数。

输入输出样例

输入样例#1:
9 5
6 10 14 2 8 8 18 5 17
1 3 1 2 1
输出样例#1:
73

说明

每个测试点1s

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

对于30%的数据有1≤N≤30,1≤M≤12。

对于50%的数据有1≤N≤120,1≤M≤50,且4种爬行卡片,每种卡片的张数不会超过20。

对于100%的数据有1≤N≤350,1≤M≤120,且4种爬行卡片,每种卡片的张数不会超过40;0≤ai≤100,1≤i≤N;1≤bi≤4,1≤i≤M。

代码:

 1 #include<cstdio>
 2 #include<algorithm>
 3 using namespace std;
 4 const int maxn=360;
 5 const int maxm=123;
 6 
 7 int n,m,point[maxn],amt[5];
 8 int dp[42][42][42][42]; 
 9 
10 void read(int &now)
11 {
12     now=0;
13     char c=getchar();
14     while(c<'0'||c>'9')
15       c=getchar();
16     while(c>='0'&&c<='9')
17       now=now*10+c-'0',c=getchar();
18 }
19 
20 int main()
21 {
22     read(n);read(m);
23     for(int i=1;i<=n;i++)
24       read(point[i]);
25     for(int num,i=1;i<=m;i++)
26       read(num),++amt[num];//amt[i]记录i卡片数量 
27     for(int i=0;i<=amt[1];i++)
28       for(int j=0;j<=amt[2];j++)
29         for(int k=0;k<=amt[3];k++)
30           for(int l=0;l<=amt[4];l++)
31           {
32                 if(i)
33                 dp[i][j][k][l]=max(dp[i][j][k][l],dp[i-1][j][k][l]);
34                 if(j)
35                   dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j-1][k][l]);
36                 if(k)
37                   dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k-1][l]);
38                 if(l)
39                   dp[i][j][k][l]=max(dp[i][j][k][l],dp[i][j][k][l-1]);
40                 dp[i][j][k][l]+=point[1+i+2*j+3*k+4*l];
41           }
42     printf("%d",dp[amt[1]][amt[2]][amt[3]][amt[4]]);
43     return 0;
44 }

优质内容筛选与推荐>>
1、L. 文件的主人和组别的设置
2、为什么有时候访问某些加密https网站是不需要证书的? https? ssl?
3、ASP入门(十九)- SELECT 语句
4、linux系统下调度数据库类型资源库中的kettle job
5、YII - 打印 SQL


长按二维码向我转账

受苹果公司新规定影响,微信 iOS 版的赞赏功能被关闭,可通过二维码转账支持公众号。

    阅读
    好看
    已推荐到看一看
    你的朋友可以在“发现”-“看一看”看到你认为好看的文章。
    已取消,“好看”想法已同步删除
    已推荐到看一看 和朋友分享想法
    最多200字,当前共 发送

    已发送

    朋友将在看一看看到

    确定
    分享你的想法...
    取消

    分享想法到看一看

    确定
    最多200字,当前共

    发送中

    网络异常,请稍后重试

    微信扫一扫
    关注该公众号





    联系我们

    欢迎来到TinyMind。

    关于TinyMind的内容或商务合作、网站建议,举报不良信息等均可联系我们。

    TinyMind客服邮箱:support@tinymind.net.cn