zoukankan      html  css  js  c++  java
  • 07noip 矩阵取数游戏 解题报告

    题目描述 Description

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

    输入描述 Input Description

    第1行为两个用空格隔开的整数n和m。
    第2~n+1 行为n*m矩阵,其中每行有m个用单个空格隔开的非负整数。

    输出描述 Output Description

    输出 仅包含1 行,为一个整数,即输入矩阵取数后的最大得分。

    样例输入 Sample Input

    2 3
    1 2 3
    3 4 2

    样例输出 Sample Output

    82

    数据范围及提示 Data Size & Hint

    样例解释

    第 1 次:第1 行取行首元素,第2 行取行尾元素,本次得分为1*21+2*21=6
    第2 次:两行均取行首元素,本次得分为2*22+3*22=20
    第3 次:得分为3*23+4*23=56。总得分为6+20+56=82

    【限制】
    60%的数据满足:1<=n, m<=30, 答案不超过1016
    100%的数据满足:1<=n, m<=80, 0<=aij<=1000

      这个题目就是一个动态规划,我们先把他每行单独拿出来看,设当矩阵剩下f[i,j]为以i为头,以j为尾的矩阵时,取到的最大值。根据题意可得只有通过f[i-1,j]和f[i,j+1]可以得到f[i,j]的状态。动态转移方程"f[i,j]=max(f[i-1,j]+f[i-1]*2^k,f[i,j+1]+f[j+1]*2^k

      根据这个题目变态的数据,我们轻而易举就能得出,这个题目需要高精度。

      代码风格略渣,不喜勿喷。

      1 program jz;
      2 type
      3  sj=array[1..20]of longint;
      4 
      5 var
      6  a:array[0..81,0..81]of longint;
      7  er:array[0..80]of sj;   //2^k
      8  e2,ans,ls,ll,lr,ls2:sj;
      9  b:array[0..81,0..81]of sj;   //f[i,j]
     10  i,j,k,t,m,n:longint;
     11 
     12 function bj(x,y:sj):boolean;  //比较大小
     13 var
     14  i,l1,l2:longint;
     15 begin
     16  l1:=20;
     17  l2:=20;
     18  while (x[l1]=0) and (l1>1) do dec(l1);
     19  while (y[l2]=0) and (l2>1) do dec(l2);
     20  if (l1>l2) then exit(true);
     21  if (l1<l2) then exit(false);
     22  for i:=l1 downto 1 do
     23   if (x[i]>y[i]) then exit(true)
     24     else if (x[i]<y[i]) then exit(false);
     25  exit(true);
     26 end;
     27 
     28 
     29 procedure gc(var x,y:sj);  //高精度乘法
     30 var
     31  i,j,l1,l2:longint;
     32  c:sj;
     33 begin
     34  l1:=20;
     35  l2:=20;
     36  while (x[l1]=0) and (l1>1) do dec(l1);
     37  while (y[l2]=0) and (l2>1) do dec(l2);
     38  fillchar(c,sizeof(c),0);
     39  for i:=1 to l1 do
     40   for j:=1 to l2 do
     41   begin
     42    c[i+j-1]:=c[i+j-1]+x[i]*y[j];
     43    c[i+j]:=c[i+j]+c[i+j-1] div 10000;
     44    c[i+j-1]:=c[i+j-1] mod 10000;
     45   end;
     46  for i:=1 to l1+l2 do
     47   if (c[i]>9999) then
     48    begin
     49    c[i+1]:=c[i] div 10000;
     50    c[i]:=c[i] mod 10000;
     51    end;
     52  x:=c;
     53 end;
     54 
     55 
     56 procedure gd(var x,y:sj);  //高精度加法
     57 var
     58  i,j,l1,l2:longint;
     59 begin
     60  l1:=20;
     61  l2:=20;
     62  while (x[l1]=0) and (l1>1) do dec(l1);
     63  while (y[l2]=0) and (l2>1) do dec(l2);
     64  if (l1<l2) then l1:=l2;
     65  for i:=1 to l2 do
     66   begin
     67   x[i]:=x[i]+y[i];
     68   x[i+1]:=x[i+1]+x[i] div 10000;
     69   x[i]:=x[i] mod 10000;
     70   end;
     71 end;
     72 
     73 
     74 begin
     75  readln(n,m);
     76  fillchar(a,sizeof(a),0);
     77  for i:=1 to n do
     78   for j:=1 to m do
     79   read(a[i,j]);
     80  e2[1]:=2;
     81  er[1][1]:=2;
     82  for i:=2 to m do //求2^k
     83   begin
     84   er[i]:=er[i-1];
     85   gc(er[i],e2);
     86   end;
     87  fillchar(ans,sizeof(ans),0);
     88  for i:=1 to n do
     89   begin
     90   fillchar(ls2,sizeof(ls2),0);
     91   for j:=1 to m do
     92    for k:=m downto j do
     93    begin
     94    t:=j-0+m-k-1;
     95    fillchar(ll,sizeof(ll),0);
     96    fillchar(lr,sizeof(lr),0);
     97    if not ((j=1) and (k=m)) then
     98     begin
     99     ll[1]:=a[i,j-1];
    100     gc(ll,er[t]);
    101     gd(ll,b[j-1,k]);
    102     lr[1]:=a[i,k+1];
    103     gc(lr,er[t]);
    104     gd(lr,b[j,k+1]);
    105     if bj(ll,lr) then
    106       b[j,k]:=ll
    107       else b[j,k]:=lr;
    108     if (j=k) then
    109      begin
    110      fillchar(ls,sizeof(ls),0);
    111      ls[1]:=a[i,j];
    112      gc(ls,er[t+1]);
    113      gd(ls,b[j,k]);
    114      b[j,k]:=ls;
    115      if bj(b[j,k],ls2) then
    116       ls2:=b[j,k];
    117      end;
    118     end;
    119    end;
    120   gd(ans,ls2);
    121   end;
    122  t:=20;
    123  while (ans[t]=0) and (t<>0) do
    124   dec(t);
    125  if (t=0) then write(0);
    126  for i:=t downto 1 do
    127   if (ans[i]>=1000) or (i=t) then
    128    write(ans[i]) 
    129    else
    130     if (ans[i]>=100) then
    131      write(0,ans[i])
    132       else
    133        if (ans[i]>=10) then
    134         write('00',ans[i])
    135          else write('000',ans[i]);
    136  writeln;
    137 end.
  • 相关阅读:
    GhostBSD 3.0RC3,基于GNOME的FreeBSD
    Nagios 3.4.3 发布,企业级监控系统
    Jolokia 1.0.6 发布, JMX远程访问方法
    微软希望开发人员不要使 WebKit 成为新版 IE6
    Kwort Linux 3.5 正式版发布
    EJDB 1.0.24 发布,嵌入式 JSON 数据库引擎
    Pale Moon 15.3 Firefox“苍月”优化版发布
    Galera Load Balancer 0.8.1 发布
    SmartSVN V7.5 正式发布
    PostgresQL建立索引如何避免写数据锁定
  • 原文地址:https://www.cnblogs.com/xstsow/p/4043189.html
Copyright © 2011-2022 走看看