免费馅饼

来源:互联网 发布: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.


 

原创粉丝点击