NOIP 提高组 2010 乌龟棋

题目大意:

乌龟棋的棋盘为1*N的矩阵,每个格子有一个分数(非负整数)。棋盘第1格是唯一的起点,第N格是终点,游戏要求玩家控制一个乌龟棋子从起点出发走到终点。
这里写图片描述
有M张爬行卡片,只有4种类型分别为1、2、3、4,使用i卡片后,乌龟棋子将向前爬行i格。
游戏中,玩家每次需要从所有的爬行卡片中选择一张之前没有使用过的爬行卡片,控制乌龟棋子前进相应的格子数,每张卡片只能使用一次。游戏中,乌龟棋子自动获得起点格子的分数,并且在后续的爬行中每到达一个格子,就得到该格子相应的分数。玩家最终游戏得分就是乌龟棋子从起点到终点过程中到过的所有格子的分数总和。
很明显,用不同的爬行卡片使用顺序会使得最终游戏的得分不同,小明想要找到一种卡片使用顺序使得最终游戏得分最多。
现在,告诉你棋盘上每个格子的分数和所有的爬行卡片,你能告诉小明,他最多能得到多少分吗?

对于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。
输入数据保证N−1=Σbi

题解:

这题我们可以猜测到做法是dp,
因为只有4种卡片且每种最多只有40种
所以我们可以设
f[i,j,k,l]表示第一种卡片用了i个第二种卡片用了j个第三种卡片用了k个,第四个卡片用了l个得到的最大分数
然后我们可以推出状态转移方程:
f[i,j,k,l]=
max{f[i-1,j,k,l]+1,f[i,j-1,k,l]+2,
f[i,j,k-1,l]+3,f[i,j,k,l-1]+4}

时间复杂度:O(N^4)

代码:

var
    f:array [-1..41,-1..41,-1..41,-1..41] of longint;
    a:array [0..351] of longint;
    num:array [1..4] of longint;
    i,j,k,l,n,m:longint;

function max(aa,bb:longint):longint;
begin
    if aa>bb then exit(aa);
    exit(bb);
end;

begin
    readln(n,m);
    for i:=1 to n do read(a[i]); readln;
    for i:=1 to m do
      begin
           read(k);
           inc(num[k]);
      end;
    readln;
    for i:=0 to num[1] do
      for j:=0 to num[2] do
        for k:=0 to num[3] do
          for l:=0 to num[4] do
          begin
             f[i,j,k,l]:=max(f[i,j,k,l],f[i-1,j,k,l]);
             f[i,j,k,l]:=max(f[i,j,k,l],f[i,j-1,k,l]);
             f[i,j,k,l]:=max(f[i,j,k,l],f[i,j,k-1,l]);
             f[i,j,k,l]:=max(f[i,j,k,l],f[i,j,k,l-1]);
             f[i,j,k,l]:=f[i,j,k,l]+a[i+2*j+3*k+4*l+1];
          end;
    writeln(f[num[1],num[2],num[3],num[4]]);
end.
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值