码迷,mamicode.com
首页 > 其他好文 > 详细

NOIP模拟赛

时间:2016-10-03 10:41:23      阅读:161      评论:0      收藏:0      [点我收藏+]

标签:

#1【Nescafé 31】杯NOIP模拟赛

t1

题意:n*m的棋盘上从(1,1)走到(n,m),只能向下或向右,一些格子有老鼠,每个老鼠互不相同,当处于与老鼠有重边的格子时,视为看见了这只老鼠,求到终点看到最少的不同老鼠数。

分析:DP 由于求得是看到的不同的老鼠数目,不能直接用过河卒做,因为同一个位置的老鼠可能会统计多次,我们还需要增加一维即方向。

  f[i,j,0]表示到从上面一个格子走到(i,j)时最少老鼠数,f[i,j,1]表示左边。

   f[i,j,0]:=min(f[i-1,j,0]+a[i,j-1],f[i-1,j,1])+a[i+1,j]+a[i,j+1];

   f[i,j,1]:=min(f[i,j-1,1]+a[i-1,j],f[i,j-1,0])+a[i+1,j]+a[i,j+1];

   对于(i,j)如果左边有老鼠,那么从(i-1,j-1)走到(i-1,j)再到(i,j)会看到该老鼠两次但只能记为1次,(i-2,j)走到(i-1,j)再到(i,j)时只看到该老鼠一次,故要加上这一次。上边有老鼠也同理。

代码:

技术分享
program mouse;
var
  a:array[0..1001,0..1001]of longint;
  f:array[0..1001,0..1001,0..1]of longint;
  n,i,m,j:longint;
function min(x,y:longint):longint;
begin
  if x<y then min:=x else min:=y;
end;
begin
  assign(input,mouse.in);
reset(input);
assign(output,mouse.out);
rewrite(output);
  readln(n,m);
  for i:=1 to n do begin
   for j:=1 to m do
     read(a[i,j]);  readln; end;
  for i:=0 to n do
    for j:=0 to m do
     begin
      f[i,j,0]:=maxlongint div 3;f[i,j,1]:=maxlongint div 3;
     end;
  f[1,1,1]:=a[1,1]+a[2,1]+a[1,2]; f[1,1,0]:=a[1,1]+a[2,1]+a[1,2];
  for i:=1 to n do
    for j:=1 to m do
    if (i<>1)or(j<>1) then
     begin
       f[i,j,0]:=min(f[i-1,j,0]+a[i,j-1],f[i-1,j,1])+a[i+1,j]+a[i,j+1];
       f[i,j,1]:=min(f[i,j-1,1]+a[i-1,j],f[i,j-1,0])+a[i+1,j]+a[i,j+1];
     end;
  writeln(min(f[n,m,1],f[n,m,0]));
  close(input); close(output);
end.
View Code

 

  

NOIP模拟赛

标签:

原文地址:http://www.cnblogs.com/qtyytq/p/5928798.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!