[Description]
Shuai often plays a matrix fetch game with his classmates: for a given n * M matrix, each element a [I, j] in the matrix 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. there is a score for each number, which is the sum of the scores for each number in each row. The score for each number = the value of the element to be removed * 2 ^ I, 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 format]
The input file game. In contains N + 1 rows:
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 format]
The output file game. Out contains only one row and is an integer, that is, the maximum score after the number of input matrices.
[Example input]
Example input 1 |
Sample input 2 |
Sample input 3 |
2 3 1 2 3 3 4 2 |
1 4 4 5 0 5 |
2 10 96 56 54 46 86 12 23 88 80 43 16 95 18 29 30 53 88 83 64 67 |
[Sample output]
Sample output 1 |
Sample output 2 |
Sample output 3 |
82 |
122 |
316994 |
[Analysis]
F [I] [J] = 2 * max {A [I] + F [I + 1] [J], f [I] [J-1] + A [J]}.
#include <stdio.h>#include <string.h>#define MAXLEN 12#define MAXN 100#define BASE 10000int a[MAXN],f[MAXN][MAXN][MAXLEN],ans[MAXLEN],tem1[MAXLEN],tem2[MAXLEN];int from[MAXN][MAXN];int n,m;int cmp(int a[],int b[]) {int l1 = a[0],l2 = b[0];if (l1 > l2)return 1;if (l1 < l2)return -1; for (int i = l1;i > 0;--i) if (a[i] > b[i]) return 1; else if (a[i] < b[i]) return -1;return 0;}void plus(int a[],int b) {a[1] += b;for (int i = 1;i < MAXLEN;++i) {a[i + 1] += a[i] / BASE;a[i] %= BASE;}for (int i = MAXLEN - 1;i > 0;--i)if (a[i]) {a[0] = i;break;}if (!a[0])a[0] = 1;}void s_plus(int a[],int b[]) {int c[MAXLEN];memset(c,0,sizeof(c));for (int i = 1;i < MAXLEN;++i) {c[i] += a[i] + b[i];c[i + 1] = c[i] / BASE;c[i] %= BASE;}for (int i = MAXLEN - 1;i > 0;--i)if (c[i]) {c[0] = i;break;}for (int i = 0;i < MAXLEN;++i)a[i] = c[i];}void cheng(int a[]) {for (int i = 1;i < MAXLEN;++i)a[i] *= 2;for (int i = 1;i < MAXLEN;++i) {a[i + 1] += a[i] / BASE;a[i] %= BASE;}for (int i = MAXLEN - 1;i > 0;--i)if (a[i]) {a[0] = i;break;}}void dp(int i,int j) {if (f[i][j][0])return;dp(i + 1,j);dp(i,j - 1);memset(tem1,0,sizeof(tem1));memset(tem2,0,sizeof(tem2));tem1[0] = f[i + 1][j][0];for (int k = 1;k <= tem1[0];++k)tem1[k] = f[i + 1][j][k];plus(tem1,a[i]);tem2[0] = f[i][j - 1][0];for (int k = 1;k <= tem2[0];++k)tem2[k] = f[i][j - 1][k];plus(tem2,a[j]);int x = cmp(tem1,tem2);if (x >= 0) {f[i][j][0] = tem1[0];for (int k = 1;k <= tem1[0];++k)f[i][j][k] = tem1[k]; from[i][j] = 1;} else {f[i][j][0] = tem2[0];for (int k = 1;k <= tem2[0];++k)f[i][j][k] = tem2[k]; from[i][j] = 2;}cheng(f[i][j]);}int main() {scanf("%d%d",&n,&m);for (int t = 1;t <= n;++t) {for (int i = 1;i <= m;++i)scanf("%d",&a[i]);memset(f,0,sizeof(f));for (int i = 1;i <= m;++i) {f[i][i][0] = 1;f[i][i][1] = a[i];cheng(f[i][i]);}dp(1,m);s_plus(ans,f[1][m]);}printf("%d",ans[ans[0]]);for (int i = ans[0] - 1;i > 0;--i)printf("%d%d%d%d",ans[i] / 1000,ans[i] / 100 % 10,ans[i] / 10 % 10,ans[i] % 10);return 0;}