zoukankan      html  css  js  c++  java
  • NOIP2007 矩阵取数游戏

    题目描述

    帅帅经常跟同学玩一个矩阵取数游戏:对于一个给定的n*m的矩阵,矩阵中的每个元素aij均为非负整数。游戏规则如下:

    1.每次取数时须从每行各取走一个元素,共n个。m次后取完矩阵所有元素;

    2.每次取走的各个元素只能是该元素所在行的行首或行尾

    3.每次取数都有一个得分值,为每行取数的得分之和,每行取数的得分 = 被取走的元素值*2^i,其中i表示第i次取数(从1开始编号);

    4.游戏结束总得分为m次取数得分之和。

    帅帅想请你帮忙写一个程序,对于任意矩阵,可以求出取数后的最大得分。

    输入输出格式

    输入格式:

    输入文件game.in包括n+1行:

    第1行为两个用空格隔开的整数n和m。

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

    数据范围:

    60%的数据满足:1<=n, m<=30,答案不超过10^16

    100%的数据满足:1<=n, m<=80,0<=aij<=1000

    输出格式:

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

    输入输出样例

    输入样例#1:
    2 3
    1 2 3
    3 4 2
    
    输出样例#1:
    82

    说明

    NOIP 2007 提高第三题

    题解思路:A:爆搜,当然,每个题都可以爆搜(就是过不过的问题了)

                       对于每一行,爆搜出最大得分,然后加起来,但是(1<=n, m<=80),显然超时

                  B:贪心,

                      对一每一行,每次取最小值,把大的向后放,额......但是,显然答案是错误的(如:5 1 1 1 4 4 4 4 4);

                  C:DP

                      对于每一行,dp[i,j]:=max(dp[i-1,j],dp[i,j+1])+w; 

                      dp[i,j]代表左端点为i,右端点为j的最大值,可以由两个状态转移而来。

                      1:上一个取得左     2:上一个取得右

                      然后再加上此步的得分。

                   然后......60,(‘^’)为啥?没高精。。。。。。

                   加上高精 100(^'-'^).

    附代码 pascal:

    const
      maxm=1000000;
      maxn=81;
    type
      arr=array[0..maxn]of longint;
    var
      n,m:longint;
      a:array[1..maxn]of longint;
      f:array[-1..maxn,-1..maxn]of arr;
      ans,maxf:arr;
      p:array[1..maxn]of arr;
    
    function add(a,b:arr):arr;
    var
      i,j,x:longint;
      c:arr;
    begin
      x:=0; i:=1;
      fillchar(c,sizeof(c),0);
      while (i<=a[0])or(i<=b[0]) do
        begin
          c[i]:=a[i]+b[i]+x;
          x:=c[i] div maxm;
          c[i]:=c[i] mod maxm;
          inc(i);
        end;
      if x>0 then
        begin
          c[0]:=i;
          c[i]:=x;
        end
      else c[0]:=i-1;
      exit(c);
    end;
    
    function gjd(k:longint;a:arr):arr;
    var
      x,i:longint;
    begin
      x:=0;
      for i:=1 to a[0] do
        begin
          a[i]:=a[i]*k+x;
          x:=a[i] div maxm;
          a[i]:=a[i] mod maxm;
        end;
      while x<>0 do
        begin
          inc(a[0]);
          a[a[0]]:=x mod maxm;
          x:=x div maxm;
        end;
      exit(a);
    end;
    
    function max(a,b:arr):arr;
    var
      i:longint;
    begin
      if a[0]>b[0] then exit(a)
      else
        if a[0]<b[0] then exit(b)
        else
          for i:=a[0] downto 1 do
            if a[i]>b[i] then exit(a)
            else if b[i]>a[i] then exit(b);
      exit(b);
    end;
    
    procedure solve;
    var
      i,j:longint;
      c,d:arr;
    begin
      fillchar(maxf,sizeof(maxf),0);
      fillchar(f,sizeof(f),0);
      for i:=0 to m do
        for j:=m+1 downto i+1 do
          f[i,j]:=max(add(f[i-1,j],gjd(a[i],p[i-j+m+1])),add(f[i,j+1],gjd(a[j],p[i-j+m+1])));
      for i:=1 to m-1 do
        maxf:=max(maxf,f[i,i+1]);
    end;
    
    procedure calc;
    var
      i,j:longint;
    begin
      p[1][0]:=1;
      p[1][1]:=2;
      for i:=2 to 80 do
        p[i]:=gjd(2,p[i-1]);
      for i:=1 to n do
        begin
          for j:=1 to m do
            read(a[j]);
          readln;
          solve;
          ans:=add(ans,maxf);
        end;
    end;
    
    procedure print;
    var
      i:longint;
    begin
      write(ans[ans[0]]);
      for i:=ans[0]-1 downto 1 do
        begin
          if ans[i]<100000 then write('0');
          if ans[i]<10000 then write('0');
          if ans[i]<1000 then write('0');
          if ans[i]<100 then write('0');
          if ans[i]<10 then write('0');
          write(ans[i]);
        end;
      writeln;
    end;
    
    begin
    
      readln(n,m);
      calc;
      print;
    
    end.
    
    

                     

  • 相关阅读:
    【Leetcode】23. Merge k Sorted Lists
    【Leetcode】109. Convert Sorted List to Binary Search Tree
    【Leetcode】142.Linked List Cycle II
    【Leetcode】143. Reorder List
    【Leetcode】147. Insertion Sort List
    【Leetcode】86. Partition List
    jenkins 配置安全邮件
    python 发送安全邮件
    phpstorm 同步远程服务器代码
    phpUnit 断言
  • 原文地址:https://www.cnblogs.com/fengjunjie/p/6016356.html
Copyright © 2011-2022 走看看