免费馅饼
来源:互联网 发布:99客服软件安卓版 编辑:程序博客网 时间:2024/04/27 16:24
【模拟试题】免费馅饼
Time Limit:10000MS Memory Limit:65536K
Total Submit:161 Accepted:69
Description
SERKOI最新推出了一种叫做“免费馅饼”的游戏:游戏在一个舞台上进行。舞台的宽度为W格,天幕的高度为H格,游戏者占一格。开始时游戏者站在舞台的正中央,手里拿着一个托盘。下图为天幕的高度为4格时某一个时刻游戏者接馅饼的情景。
游戏开始后,从舞台天幕顶端的格子中不断出现馅饼并垂直下落。游戏者左右移动去接馅饼。游戏者每秒可以向左或向右移动一格或两格,也可以站在原地不动。
馅饼有很多种,游戏者事先根据自己的口味,对各种馅饼依次打了分。同时,在8-308电脑的遥控下,各种馅饼下落的速度也是不一样的,下落速度以格/秒为单位。
当馅饼在某一秒末恰好到达游戏者所在的格子中,游戏者就收集到了这块馅饼。
写一个程序,帮助我们的游戏者收集馅饼,使得所收集馅饼的分数之和最大。
Input
输入文件的第一行是用空格隔开的两个正整数,分别给出了舞台的宽度W(1到99之间的奇数)和高度H(1到100之间的整数)。
接下来依馅饼的初始下落时间顺序给出了所有馅饼的信息。每一行给出了一块馅饼的信息。由四个正整数组成,分别表示了馅饼的初始下落时刻(0到1000秒),水平位置、下落速度(1到100)以及分值。游戏开始时刻为0。从1开始自左向右依次对水平方向的每格编号。
输入文件中同一行相邻两项之间用一个或多个空格隔开。
Output
输出只有一行,为一个正整数,表示你的程序所收集的最大分数之和。
Sample Input
3 3 0 1 2 5 0 2 1 3 1 2 1 3 1 3 1 4
Sample Output
12
【解析】
设f[i,j]为第i时刻第在j个格子所能获得的最大价值。
不难想到动规状态转移方程为f[i,j]=max{f[i-1,k]}(k=-2,-1,-,1,2);
需要注意的问题是,有一些点在某些时刻是不可能到达的,因此直接转移会出现错误,应当先预处理出第i时刻第j个格子是否可达,用can[i,j]表示,作为转移方程的限制条件。
这个程序写丑了。
var f,v:array[0..1101,1..100] of longint; can:array[0..1101,-1..102] of boolean; w,h,x0:longint;procedure init;var i,k,t0,x,v0,s,tem:longint;begin readln(w,h); fillchar(f,sizeof(f),0); fillchar(v,sizeof(v),0); while not eof do //for i:=1 to 4 do begin readln(t0,x,v0,s); if ((h-1) mod v0) <> 0 then continue; tem:=t0+((h-1) div v0); inc(v[tem,x],s); end; fillchar(can,sizeof(can),0); x0:=w shr 1+1; can[0,x0]:=true; for k:=1 to 1101 do for i:=1 to w do if can[k-1,i-2] or can[k-1,i-1] or can[k-1,i] or can[k-1,i+1] or can[k-1,i+2] then can[k,i]:=true;end;function max(a,b,c,d,e:longint):longint;begin max:=a; if b>max then max:=b; if c>max then max:=c; if d>max then max:=d; if e>max then max:=e;end;procedure dp;var i,k,ans:longint;begin f[0,x0]:=v[0,x0]; for k:=1 to 1101 do for i:=1 to w do if can[k,i] then begin if i=1 then begin f[k,i]:=max(f[k-1,i+1],f[k-1,i+2],f[k-1,i],0,0)+v[k,i]; continue; end; if i=2 then begin f[k,i]:=max(f[k-1,i+1],f[k-1,i+2],f[k-1,i],f[k-1,i-1],0)+v[k,i]; continue; end; if i=w then begin f[k,i]:=max(f[k-1,i],f[k-1,i-1],f[k-1,i-2],0,0)+v[k,i]; continue; end; if i=w-1 then begin f[k,i]:=max(f[k-1,i+1],f[k-1,i],f[k-1,i-1],f[k-1,i-2],0)+v[k,i]; continue; end; f[k,i]:=max(f[k-1,i-2],f[k-1,i-1],f[k-1,i],f[k-1,i+1],f[k-1,i+2])+v[k,i]; end; ans:=0; for i:=1 to w do if f[1101,i]>ans then ans:=f[1101,i]; writeln(ans);end;begin init; dp;end.
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 免费馅饼
- 在命令窗口中编写pl/sql编写函数,并执行调用
- 读《编码的奥秘》有感
- Ubuntu(Linux)使用Eclipse搭建C/C++编译环境
- 快速查看CENTOS发行版本
- float与double类型的内存分布,精度和范围
- 免费馅饼
- 一种存储过程输出参数的用法
- C# 在采集数据时的验证与登录处理
- 犯错反省出梦想
- 用于提取纯真数据库IP地址列表的python小程序(使用正则表达式)
- Hibernate中Criteria的完整用法
- css兼容IE8
- 如何在网页HTML中嵌入QQ、MSN、旺旺、Gtalk快速对话框代码
- 用C#创建Windows服务(Windows Services)