DescriptionDescription
[Problem description]
Shuai often plays a matrix fetch game with his classmates: for a given n * M matrix, each element of the matrix AIJ is
It is a non-negative integer. The rules are as follows:
1. Each time the number is obtained, one element must be taken from each row, N in total. After M, all elements of the matrix are obtained;
2. Each element removed each time can only be the first or end of the row where the element is located;
3. Each number fetch has a score, which is the sum of the scores of each number in each row. The score of each number is equal to the value of the removed element * 2I,
Where I indicates the number of the I-th fetch (starting from 1 );
4. The total score of the game end is the sum of the score of M-times.
Shuai would like to ask you to write a program. For any matrix, you can find the maximum score after the number is obtained.
Input description
Input description
1st act two integers n and m separated by spaces.
2nd ~ N + 1 Act N * M matrix, where each line has m non-negative integers separated by a single space.
Output description
Output description
The output contains only one row and is an integer, that is, the maximum score after the number of input matrices.
Sample Input
Sample Input
2 3
1 2 3
3 4 2
Sample output
Sample output
82
Data range and prompt
Data size & hint
Example
1st times: the first element of the row is taken for the second row, and the last element of the row is taken for the second row. The score is 1*21 + 2*21 = 6.
2nd times: Both rows take the first element of the row. The score is 2*22 + 3*22 = 20.
3rd Times: The score is 3*23 + 4*23 = 56. Total score: 6 + 20 + 56 = 82
[Restrictions]
60% of data meets the requirements: 1 <= n, m <= 30, and the answer should not exceed 1016
100% of data meets the requirements: 1 <= n, m <= 80, 0 <= AIJ <= 1000
Analysis
The optimal sub-structure of this question and subproblem overlap are very obvious, it is easy to write the state transition equation of the range dynamic gauge: Fl, I, j = max {(FL, I-1, J + 2X * Al, I-1), (FL, I, j + 1 +
2
X * Al, J + 1 )}
The proof is relatively simple. Here is not the focus of the discussion...Let's take a look at the data range. m can reach up to 80, AI, and J can reach up to 1000, obviously beyond the range of int64 (heard Pascal say there is a data type like int128 ?), We have no way to use C ++, so we have to use high-precision pressure bit .. Considering that there is only "high precision * int" in "multiplication", multiplication can be shamelessly changed to multiplication → _ → multiplication is ruled out. When the bit is pressed, it is recommended to press a few more places to save resources (test results: it takes 375 ms to press 8-Bit High-Precision Open 5-bit)
1 # include <cstdio>
2 # define mod 100000000
3 using namespace STD;
4 int M [81] [81] = {0}, n, m;
5 struct big
6 {
7 int num [5], Len;
8 big () {Len = 1; num [0] = 0 ;}
9 big (int K ){
10 Len = 1, num [0] = K % mod, K/= MOD;
11 while (k)
12 num [Len ++] = K % mod, K/= MOD;
13}
14 big & operator + = (const big & B ){
15 int m = 0, I;
16 For (I = 0; I <Len | I <B. Len | M; ++ I ){
17 if (I <Len) m + = num [I];
18 if (I <B. Len) m + = B. Num [I];
19 num [I] = m % MOD;
20 m/= MOD;
21}
22 if (I> Len) Len = I;
23 return * this;
24}
25 big operator + (const big & B ){
26 big ans = * This; ans + = B;
27 return ans;
28}
29 big operator * (int B) const {
30 big ans = 0, K = * this;
31 while (B ){
32 If (B & 1) ans + = K;
33 K + = K;
34 B> = 1;
35}
36 return ans;
37}
38 bool operator> (const big & B) const {
39 if (Len! = B. Len) return Len> B. Len;
40 int I = Len;
41 while (-- I> = 0)
42 if (Num [I]! = B. Num [I]) return num [I]> B. Num [I];
43 return 0;
44}
45} s [81] [81];
46 int main ()
47 {
48 int I, j, T;
49 scanf ("% d", & N, & M );
50 big ans, PO2 [81] = {1 };
51 for (I = 1; I <= m; ++ I)
52 PO2 [I] = PO2 [I-1] * 2;
53 For (I = 0; I <n; ++ I)
54 For (j = 0; j <m; ++ J)
55 scanf ("% d", M [I] + J );
56 for (t = 0; t <n; ++ t ){
57 big temp, ans;
58 s [0] [m] = 0;
59 for (j = s-1; j> = 0; -- J)
60 s [0] [J] = s [0] [J + 1] + PO2 [M-J] * m [T] [J];
61 ans = s [0] [0];
62 for (I = 1; I <= m; ++ I)
63 s [I] [m] = s [I-1] [m] + PO2 [I] * m [T] [I-1];
64 if (s [m] [m]> ans) ans = s [m] [m];
65 for (I = 1; I <m; ++ I ){
66 for (j = m-1; j> = I; -- j ){
67 If (s [I-1] [J] + PO2 [M + I-j] * m [T] [I-1]> S [I] [J + 1] + PO2 [m + I-j] * m [T] [J])
68 s [I] [J] = s [I-1] [J] + PO2 [M + I-j] * m [T] [I-1];
69 else s [I] [J] = s [I] [J + 1] + PO2 [M + I-j] * m [T] [J];
70}
71 If (s [I] [I]> ans) ans = s [I] [I];
72}
73 ans + = ans;
74}
75 I = ans. Len;
76 printf ("% d", ANS. Num [-- I]);
77 while (I)
78 printf ("% 08d", ANS. Num [-- I]);
79 return 0;
80}