NOIP2010提高组乌龟棋 -SilverN

题目背景

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

题目描述

乌龟棋的棋盘是一行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 /*NOIP2010提高组乌龟棋         SilverN*/
 2 #include<iostream>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<cmath>
 6 using namespace std;
 7 int f[50][50][50][50];
 8 int s[500];//得分
 9 int p[5];//卡数量
10 int m,n;
11 int main(){
12     scanf("%d%d",&n,&m);
13     int i,j,x;
14     for(i=1;i<=n;i++)scanf("%d",&s[i]);
15     for(j=1;j<=m;j++){//计算卡数量
16         scanf("%d",&x);
17         p[x]++;
18     }
19     int k,h;
20     //枚举卡的使用数量即可,注意可以不使用卡
21     for(i=0;i<=p[1];i++)
22       for(j=0;j<=p[2];j++)
23         for(k=0;k<=p[3];k++)
24           for(h=0;h<=p[4];h++){
25               int dis=i+2*j+3*k+4*h+1;
26               if(i>0 && f[i-1][j][k][h]>f[i][j][k][h] )f[i][j][k][h]=f[i-1][j][k][h];
27               if(j>0 && f[i][j-1][k][h]>f[i][j][k][h] )f[i][j][k][h]=f[i][j-1][k][h];
28               if(k>0 && f[i][j][k-1][h]>f[i][j][k][h] )f[i][j][k][h]=f[i][j][k-1][h];
29               if(h>0 && f[i][j][k][h-1]>f[i][j][k][h] )f[i][j][k][h]=f[i][j][k][h-1];
30               f[i][j][k][h]+=s[dis];
31           }
32     printf("%d",f[p[1]][p[2]][p[3]][p[4]]);//数据保证所有卡用完以后到终点
33     return 0;
34 }
时间: 2024-10-10 04:40:13

NOIP2010提高组乌龟棋 -SilverN的相关文章

NOIP2010提高组 关押罪犯 -SilverN

(洛谷P1525) 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到S 城Z 市长那里.公务繁忙的

noip2010提高组题解

NOIP2010提高组题解 T1:机器翻译 题目大意:顺序输入n个数,有一个队列容量为m,遇到未出现元素入队,求入队次数. AC做法:直接开1000的队列模拟过程. T2:乌龟棋 题目大意:有长度为n的棋盘,每个格子对应一个分数,1,2,3,4的卡片共m张,给出四种卡片各自的数量,求改变出牌顺序能获得的最大分数. 思路:开了一个四维的f[i][j][k][l]来表示每张牌有了几张时的最大分数: F[i][j][k][l]=max(f[i-1][j][k][l],f[i][j-1][k][l],f

NOIP2010 提高组 洛谷P1525 关押罪犯

刚才做并查集想到了这道以前做的题,干脆一并放上来 题目描述 S 城现有两座监狱,一共关押着N 名罪犯,编号分别为1~N.他们之间的关系自然也极不和谐.很多罪犯之间甚至积怨已久,如果客观条件具备则随时可能爆发冲突.我们用“怨气值”(一个正整数值)来表示某两名罪犯之间的仇恨程度,怨气值越大,则这两名罪犯之间的积怨越多.如果两名怨气值为c 的罪犯被关押在同一监狱,他们俩之间会发生摩擦,并造成影响力为c 的冲突事件. 每年年末,警察局会将本年内监狱中的所有冲突事件按影响力从大到小排成一个列表,然后上报到

[NOIP2010] 提高组 洛谷P1541 乌龟棋

题目背景 小明过生日的时候,爸爸送给他一副乌龟棋当作礼物. 题目描述 乌龟棋的棋盘是一行N个格子,每个格子上一个分数(非负整数).棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点. 乌龟棋中M张爬行卡片,分成4种不同的类型(M张卡片中不一定包含所有4种类型的卡片,见样例),每种类型的卡片上分别标有1.2.3.4四个数字之一,表示使用这种卡片后,乌龟棋子将向前爬行相应的格子数.游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前

NOIP2010提高组 机器翻译 -SilverN

1 /**/ 2 #include<iostream> 3 #include<cstdio> 4 #include<cmath> 5 #include<cstring> 6 #include<algorithm> 7 using namespace std; 8 int head=0,tail=0; 9 int t[2000]={0}; 10 int x,c=0; 11 int m,n; 12 int main(){ 13 cin>>

[NOIP2010] 提高组 洛谷P1540 机器翻译

题目背景 小晨的电脑上安装了一个机器翻译软件,他经常用这个软件来翻译英语文章. 题目描述 这个翻译软件的原理很简单,它只是从头到尾,依次将每个英文单词用对应的中文含义来替换.对于每个英文单词,软件会先在内存中查找这个单词的中文含义,如果内存中有,软件就会用它进行翻译:如果内存中没有,软件就会在外存中的词典内查找,查出单词的中文含义然后翻译,并将这个单词和译义放入内存,以备后续的查找和翻译. 假设内存中有M个单元,每单元能存放一个单词和译义.每当软件将一个新单词存入内存前,如果当前内存中已存入的单

NOIP2010提高组--机械翻译

分析:可以一遍循环扫描,然后已有的就跳过,没有的就写入.而所谓的最早写用可以理解为从0开始到末尾再次回到0,可以用一个量来标记位置,而无需想哪个最早写. 1 #include <stdio.h> 2 #include<string.h> 3 int main() 4 { 5 int M,N,sen[1001]; 6 int con[1000]; 7 int i,j,sign=0; 8 int now=0; //now指向当前该替换内存的位置 9 int num=0; 10 freo

NOIP2010普及组 三国游戏 -SilverN

1 #include<iostream> 2 #include<cstdio> 3 #include<algorithm> 4 #include<cmath> 5 using namespace std; 6 int d[510][510]; 7 int n; 8 int fst,snd,ans; 9 int main(){ 10 scanf("%d",&n); 11 int i,j,x; 12 for(i=1;i<n;i+

[NOIP2010提高组]引水入城

题目:洛谷P1514.Vijos P1777.codevs1066. 题目大意:有一个$n×m$的矩阵,每个点都有一个高度,可以在第一行的任意点建立蓄水厂.现在要把水输到最后一行的所有点上,规定水只能流到高度比当前点小的点上.先让你判断能否输到所有点上,如能,输出最少建多少个蓄水厂:如不能,输出最多能输到几个点上. 解题思路:首先把第一行所有点塞进队列里,跑BFS,找出所有能到的点,然后判断能否输到最后一行所有点上.如果不能,输出最后一行能被输到的点的总数.如果能的话,我们依次把第一行每个点能输