SSL 1558——科技庄园

Description

由于PFT不是机器人,所以他的体力并不是无限的,他不想摘很多的桃以至体力为0,而白白把桃给Life。同时PFT每次只能摘一棵桃树,摘桃花费时间体力,每棵桃树都可以摘K次(对于同一棵桃每次摘的桃数相同)。每次摘完后都要返回出发点(PFT一次拿不了很多)即Life的所在地(0,0){试验田左上角的桃坐标是(1,1)}。
PFT每秒只能移动一个单位,每移动一个单位耗费体力1(摘取不花费时间和体力,但只限上下左右移动)。

Input

第一行:四个数为N,M,TI,A 分别表示试验田的长和宽,Life给PFT的时间,和PFT的体力。
下面一个N行M列的矩阵桃田。表示每次每棵桃树上能摘的桃数。
接下来N行M列的矩阵,表示每棵桃最多可以采摘的次数K。

Output

一个数:PFT可以获得的最大的桃个数。

Sample Input

4 4 13 20
10 0 0 0
0 0 10 0
0 0 10 0
0 0 0 0
1 0 0 0
0 0 2 0
0 0 4 0
0 0 0 0
【样例解释】
可以摘到1次(1,1)和1次(2,3),体力和时间不满足再摘桃了。

Sample Output

10
Hint

对于M N TI A
10<=30%<=50
10<=100%<=100
对于K
10<=100%<=100
保证结果在longint范围内


因为每摘一次都要回到起点,所以我们在预处理时,就将摘这棵桃树一次耗费的时间求出。
枚举桃树、时间和这棵桃树能摘的次数
状态转移方程:f[j]:=max(f[j],f[j-w[i]*k]+c[i]*k);


代码如下:

var
  a,b:array[1..1000,1..1000] of longint;
  w,c,u,f:array[0..10000]of longint;
  n,m,i,j,k,v,t,p:longint;
function max(x,y:longint):longint;
  begin
    if x>y then exit(x);
    exit(y);
end;
begin
  readln(n,m,t,p);
  k:=0;
  for i:=1 to n do
    for j:=1 to m do
      read(a[i,j]);
  for i:=1 to n do
    for j:=1 to m do
      begin
        read(b[i,j]);
        if a[i,j]>0 then
          begin
            inc(k);
            c[k]:=a[i,j];
            u[k]:=b[i,j];
            w[k]:=(i+j)*2;
          end;
      end;
  v:=k;
  for i:=1 to v do
    for j:=t downto 0 do
      for k:=0 to u[i] do
        if (j>=w[i]*k) then f[j]:=max(f[j],f[j-w[i]*k]+c[i]*k);
  if t>=p then t:=p-1;
  writeln(f[t]);
end.
原文地址:https://www.cnblogs.com/Comfortable/p/8412308.html