• vijos 1563 疯狂的方格取数


    P1653疯狂的方格取数
     

    背景

    Due to the talent of talent123,当talent123做完NOIP考了两次的二取方格数和vijos中的三取方格数后,突发奇想....

    描述

    在一个宽M,长N的矩阵中,请你编一个程序,n次从矩阵的左上角走到矩阵的右下角,每到一处,就取走该处的数字,请你选择一
    种走法使取得的数字的和最大,并输出其最大值。其中:3<=M<=20 M<=N<=100 1<=n<=10

    如输入数据:
    3 10 13

    0 1 2 3 4 9 7 1 3 1
    9 1 2 2 3 6 7 8 1 2
    1 2 3 4 5 9 8 7 6 1
    9 7 1 3 1 9 1 2 2 3
    6 7 8 1 2 1 2 3 4 5
    9 1 2 2 3 6 7 8 1 2
    1 2 3 4 5 9 8 7 6 1
    9 7 1 3 1 9 1 2 2 3
    6 7 8 1 2 1 2 3 4 5
    9 1 2 2 3 6 7 8 1 2
    1 2 3 4 5 9 8 7 6 1
    9 7 1 3 1 9 1 2 2 3
    6 7 8 1 2 1 2 3 4 0
    其中n=3
    M=10
    N=13
    即当n=3时,就相当于是3取方格数。

    对于以上的数据:
    将输出:297
    //注:如过你想到了无记忆性搜所的方法(不管你怎样优化),你可以直接放弃这道题了。

    //提示1:动态规划如果用的是二位数组,规模为100*100000即可。

    //提示2:如果你坚信自己的程序已经无可优化了,可有2个数据依然超时,那么告诉你,存在数据有M<n的情况!!!

    格式

    输入格式

    第一行:三个整数:n M N
    以下的N行每行M个数字,代表你要处理的矩阵。

    输出格式

    只有一行:你所取得的数字的和。

    样例1

    样例输入1[复制]

     
    4 6 7
    0 2 3 4 5 6
    6 5 4 3 2 1
    0 9 8 7 6 5
    12 3 4 5 6 7
    0 0 0 1 2 3
    12 23 34 45 1 23
    4 5 6 6 1 0

    样例输出1[复制]

     
    265

    限制

    共有10个测试数据,每个测试数据包含1个测试点,每个测试点的时间限制为2秒钟。

    来源

    本题目来自:北京市,中关村中学,高三9班,孙一(网名:talent123

    题解:

    当年的难题如今终于轻松解决了……

    不多说了,水题一道……

    网络流想几道基本上就差不多了……

    最大费用最大流

    代码:

    方法一:将费用取负

      1 uses math;
      2 const inf=maxlongint;
      3 type node=record
      4      from,go,next,v,c:longint;
      5      end;
      6 var e:array[0..200000] of node;
      7     pre,head,q,d:array[0..100000] of longint;
      8     v:array[0..100000] of boolean;
      9     num:array[0..100,0..100] of longint;
     10     i,j,n,s,t,l,r,mincost,tot,k,x,m:longint;
     11 procedure ins(x,y,z,w:longint);
     12  begin
     13  inc(tot);
     14  with e[tot] do
     15   begin
     16   from:=x;go:=y;v:=z;c:=w;next:=head[x];head[x]:=tot;
     17   end;
     18  end;
     19 procedure insert(x,y,z,w:longint);
     20  begin
     21  if y>100000 then exit;
     22  ins(x,y,z,w);ins(y,x,0,-w);
     23  end;
     24 function spfa:boolean;
     25  var i,x,y:longint;
     26  begin
     27  fillchar(v,sizeof(v),false);
     28  for i:=s to t do d[i]:=inf;
     29  l:=0;r:=1;q[1]:=s;d[s]:=0;v[s]:=true;
     30  while l<r do
     31   begin
     32   inc(l);
     33   x:=q[l];v[x]:=false;
     34   i:=head[x];
     35   while i<>0 do
     36    begin
     37    y:=e[i].go;
     38    if (e[i].v<>0) and (d[x]+e[i].c<d[y]) then
     39     begin
     40     d[y]:=d[x]+e[i].c;
     41     pre[y]:=i;
     42     if not(v[y]) then
     43      begin
     44      v[y]:=true;
     45      inc(r);
     46      q[r]:=y;
     47      end;
     48     end;
     49    i:=e[i].next;
     50   end;
     51  end;
     52  exit(d[t]<>inf);
     53  end;
     54 procedure mcf;
     55  var i,tmp:longint;
     56  begin
     57  mincost:=0;
     58  while spfa do
     59   begin
     60   tmp:=inf;
     61   i:=pre[t];
     62   while i<>0 do
     63    begin
     64    tmp:=min(tmp,e[i].v);
     65    i:=pre[e[i].from];
     66    end;
     67   inc(mincost,tmp*d[t]);
     68   i:=pre[t];
     69   while i<>0 do
     70    begin
     71    dec(e[i].v,tmp);
     72    inc(e[i xor 1].v,tmp);
     73    i:=pre[e[i].from];
     74    end;
     75   end;
     76  end;
     77 procedure init;
     78  begin
     79  tot:=1;
     80  readln(k,m,n);
     81  s:=0;t:=2*n*m+1;
     82  insert(s,1,k,0);insert(2*n*m,t,k,0);
     83  fillchar(num,sizeof(num),60);
     84  for i:=1 to n do for j:=1 to m do num[i,j]:=(i-1)*m+j;
     85  for i:=1 to n do
     86   begin
     87    for j:=1 to m do
     88     begin
     89      read(x);
     90      insert(num[i,j],num[i,j]+n*m,1,-x);
     91      insert(num[i,j],num[i,j]+n*m,inf,0);
     92      insert(num[i,j]+n*m,num[i+1,j],inf,0);
     93      insert(num[i,j]+n*m,num[i,j+1],inf,0);
     94     end;
     95   readln;
     96   end;
     97  end;
     98 procedure main;
     99  begin
    100  mincost:=0;
    101  mcf;
    102  writeln(-mincost);
    103  end;
    104 begin
    105  assign(input,'input.txt');assign(output,'output.txt');
    106  reset(input);rewrite(output);
    107  init;
    108  if k=0 then writeln(0) else main;
    109  close(input);close(output);
    110 end.    
    View Code

    方法二:直接在spfa中把<改成>,其余一些预处理做修改

      1 uses math;
      2 const inf=maxlongint;
      3 type node=record
      4      from,go,next,v,c:longint;
      5      end;
      6 var e:array[0..200000] of node;
      7     pre,head,q,d:array[0..100000] of longint;
      8     v:array[0..100000] of boolean;
      9     num:array[0..100,0..100] of longint;
     10     i,j,n,s,t,l,r,mincost,tot,k,x,m:longint;
     11 procedure ins(x,y,z,w:longint);
     12  begin
     13  inc(tot);
     14  with e[tot] do
     15   begin
     16   from:=x;go:=y;v:=z;c:=w;next:=head[x];head[x]:=tot;
     17   end;
     18  end;
     19 procedure insert(x,y,z,w:longint);
     20  begin
     21  if y>100000 then exit;
     22  ins(x,y,z,w);ins(y,x,0,-w);
     23  end;
     24 function spfa:boolean;
     25  var i,x,y:longint;
     26  begin
     27  fillchar(v,sizeof(v),false);
     28  for i:=s to t do d[i]:=-1;
     29  l:=0;r:=1;q[1]:=s;d[s]:=0;v[s]:=true;
     30  while l<r do
     31   begin
     32   inc(l);
     33   x:=q[l];v[x]:=false;
     34   i:=head[x];
     35   while i<>0 do
     36    begin
     37    y:=e[i].go;
     38    if (e[i].v<>0) and (d[x]+e[i].c>d[y]) then
     39     begin
     40     d[y]:=d[x]+e[i].c;
     41     pre[y]:=i;
     42     if not(v[y]) then
     43      begin
     44      v[y]:=true;
     45      inc(r);
     46      q[r]:=y;
     47      end;
     48     end;
     49    i:=e[i].next;
     50   end;
     51  end;
     52  exit(d[t]<>-1);
     53  end;
     54 procedure mcf;
     55  var i,tmp:longint;
     56  begin
     57  mincost:=0;
     58  while spfa do
     59   begin
     60   tmp:=inf;
     61   i:=pre[t];
     62   while i<>0 do
     63    begin
     64    tmp:=min(tmp,e[i].v);
     65    i:=pre[e[i].from];
     66    end;
     67   inc(mincost,tmp*d[t]);
     68   i:=pre[t];
     69   while i<>0 do
     70    begin
     71    dec(e[i].v,tmp);
     72    inc(e[i xor 1].v,tmp);
     73    i:=pre[e[i].from];
     74    end;
     75   end;
     76  end;
     77 procedure init;
     78  begin
     79  tot:=1;
     80  readln(k,m,n);
     81  s:=0;t:=2*n*m+1;
     82  insert(s,1,k,0);insert(2*n*m,t,k,0);
     83  fillchar(num,sizeof(num),60);
     84  for i:=1 to n do for j:=1 to m do num[i,j]:=(i-1)*m+j;
     85  for i:=1 to n do
     86   begin
     87    for j:=1 to m do
     88     begin
     89      read(x);
     90      insert(num[i,j],num[i,j]+n*m,1,x);
     91      insert(num[i,j],num[i,j]+n*m,inf,0);
     92      insert(num[i,j]+n*m,num[i+1,j],inf,0);
     93      insert(num[i,j]+n*m,num[i,j+1],inf,0);
     94     end;
     95   readln;
     96   end;
     97  end;
     98 procedure main;
     99  begin
    100  mincost:=0;
    101  mcf;
    102  writeln(mincost);
    103  end;
    104 begin
    105  assign(input,'input.txt');assign(output,'output.txt');
    106  reset(input);rewrite(output);
    107  init;
    108  if k=0 then writeln(0) else main;
    109  close(input);close(output);
    110 end.
    111          
    View Code
  • 相关阅读:
    (转)linux书籍推荐
    (转)X Windows与GNOME,KDE的关系
    (转)学习Linux编程开发必读书籍
    (转)详解C中volatile关键字
    博客开张了
    VMware虚拟产品简介
    c++ eof()
    旋转矩阵
    VMware文件辨别
    Microsoft HTTPAPI/2.0 use Port 80 – 无法启动WAMP Apache
  • 原文地址:https://www.cnblogs.com/zyfzyf/p/3841344.html
Copyright © 2020-2023  润新知