codevs天梯 矩阵取数游戏(昨天太忙没放题上来。。。)高精度+dp

来源:互联网 发布:兰州ps软件班 编辑:程序博客网 时间:2024/06/01 10:48

题目:

【问题描述】
帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m 的矩阵,矩阵中的每个元素aij均
为非负整数。游戏规则如下:
1. 每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;
2. 每次取走的各个元素只能是该元素所在行的行首或行尾;
3. 每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分= 被取走的元素值*2i
其中i 表示第i 次取数(从1 开始编号);
4. 游戏结束总得分为m次取数得分之和。
帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

分析:

很恶心,主要用dp来解题,但是dp其实很短长的是高精度- -,状态转移方程:  f[i,j,k]:=max(ggj(f[i,j,k-1],mul(a[i,k],m-k+j)),ggj(f[i,j+1,k],mul(a[i,j],m-k+j)));

代码:

const
  maxn=100;


var
  a:array [0..maxn,0..maxn] of ansistring;
  f:array [0..maxn,0..maxn,0..maxn] of ansistring;
  n,m,num:longint;
  ans:ansistring;


procedure init;
var
  i,j:longint;
begin
  readln(n,m);
  for i:=1 to n do
    for j:=1 to m do
      begin
        read(num);
        str(num,a[i,j]);
      end;
end;


function mul(s1:ansistring;temp:longint):ansistring;
var
  c:array [1..maxn*maxn*maxn] of int64;
  i,j,k:longint;
  st:ansistring;
begin
  k:=length(s1);
  fillchar(c,sizeof(c),0);
  for i:=1 to k do
    c[k+1-i]:=ord(s1[i])-ord('0');
  for i:=1 to k do
    for j:=1 to temp do
      c[i]:=c[i]*2;
  for i:=1 to k do
    begin
      c[i+1]:=c[i+1]+c[i] div 10;
      c[i]:=c[i] mod 10;
    end;
  if c[k+1]>0 then
    inc(k);
  while c[k]>=10 do
    begin
      c[k+1]:=c[k] div 10;
      c[k]:=c[k] mod 10;
      inc(k);
    end;
  for i:=1 to k do
    st:=chr(ord('0')+c[i])+st;
  mul:=st;
end;


function ggj(s1,s2:ansistring):ansistring;
var
  b,c:array [0..maxn*maxn*maxn] of int64;
  i,len1,len2:longint;
  st:ansistring;
begin
  fillchar(b,sizeof(b),0);
  fillchar(c,sizeof(c),0);
  len1:=length(s1);
  len2:=length(s2);
  for i:=1 to len1 do
    b[len1-i+1]:=ord(s1[i])-ord('0');
  for i:=1 to len2 do
    c[len2-i+1]:=ord(s2[i])-ord('0');
  if len1>len2 then
    begin
      for i:=1 to len1 do
        c[i]:=c[i]+b[i];
      for i:=1 to len1 do
        begin
          c[i+1]:=c[i+1]+c[i]div 10;
          c[i]:=c[i]mod 10;
        end;
      if c[len1+1]>0 then
        inc(len1);
      for i:=1 to len1 do
        st:=chr(c[i]+ord('0'))+st;
    end
  else
    begin
      for i:=1 to len2 do
        c[i]:=c[i]+b[i];
      for i:=1 to len2 do
        begin
          c[i+1]:=c[i+1]+c[i]div 10;
          c[i]:=c[i]mod 10;
        end;
      if c[len2+1]>0 then
        inc(len2);
      for i:=1 to len2 do
        st:=chr(c[i]+ord('0'))+st;
    end;
  ggj:=st;
end;


function max(s1,s2:ansistring):ansistring;
begin
  if length(s1)>length(s2) then
    exit(s1)
  else
    if length(s2)>length(s1) then
      exit(s2)
    else
      if s1>s2 then
        exit(s1)
      else
        exit(s2);
end;


procedure main;
var
  i,j,k:longint;
begin
  for i:=1 to n do
    for j:=m downto 1 do
      for k:=j to m do
        f[i,j,k]:=max(ggj(f[i,j,k-1],mul(a[i,k],m-k+j)),ggj(f[i,j+1,k],mul(a[i,j],m-k+j)));
  for i:=1 to n do
    ans:=ggj(ans,f[i,1,m]);
  writeln(ans);
end;


begin
  init;
  main;
end.

0 0
原创粉丝点击