区间型动态规划 之 CODE[VS] 矩阵取数游戏 (2007年NOIP全国联赛提高组)

/*
分析:
对于n行输入,各行之间是独立的,只需要找到各行的最大值,它们的和即为答案。
由于:1<=n, m<=80,0<=aij<=1000,所以最大会出现 1000*(2^80) => 高精度计算
 
dp[i][j] := 每行取第i到j个数可得到的最大值。
对于输入的任一行a[m],第x次取数的状态转移为:
dp[i][j] = 2*max(dp[i+1][j]+arr[i],dp[i][j-1]+arr[j])
(正常取数是由外向内,但步长是由小到大,相当于取数是由内向外,所以2要乘在外面,这样倍数会自然乘上)
 
*/
  1 #include <iostream>
  2 #include <cstdlib>
  3 #include <cstdio>
  4 #include <cstddef>
  5 #include <iterator>
  6 #include <algorithm>
  7 #include <locale>
  8 #include <cmath>
  9 #include <vector>
 10 #include <cstring>
 11 using namespace std;
 12 const int INF = 0x3f3f3f3f;
 13 const int MaxN = 85;
 14 const int MaxLen = 30;
 15 
 16 int n, m;
 17 
 18 struct node 
 19 {
 20     int arr[MaxLen];
 21     int len;
 22     node ()
 23     {
 24         memset(arr, 0, sizeof(arr));
 25         len = 0;
 26     }
 27 };
 28 
 29 int arr[MaxN];
 30 
 31 // a*2
 32 node Mul(node a)
 33 {
 34     int carry = 0;
 35     for (int i = 0; i < a.len; ++i)
 36     {
 37         a.arr[i] = (a.arr[i] << 1) + carry;
 38         carry = a.arr[i] / 10;
 39         a.arr[i] %= 10;
 40     }
 41     if (carry != 0)
 42     {
 43         a.arr[a.len] = carry;
 44         ++(a.len);
 45     }
 46     return a;
 47 }
 48 
 49 node Add(node a, int val)
 50 {
 51     int carry = 0;
 52     for (int i = 0; i < a.len; ++i) {
 53         a.arr[i] += (val % 10 + carry);
 54         val /= 10;
 55         carry = a.arr[i] / 10;
 56         a.arr[i] %= 10;
 57     }
 58     while (val)
 59     {
 60         a.arr[a.len] += (val % 10 + carry);
 61         val /= 10;
 62         carry = a.arr[a.len] / 10;
 63         a.arr[a.len] %= 10;
 64         ++(a.len);
 65     }
 66     if (carry)
 67     {
 68         a.arr[a.len] = carry;
 69         ++(a.len);
 70     }
 71     return a;
 72 }
 73 
 74 
 75 node Add(node a, node b)
 76 {
 77     node tmp;
 78     int carry = 0;
 79     int len = max(a.len, b.len);
 80     for (int i = 0; i < len; ++i)
 81     {
 82         tmp.arr[i] = a.arr[i] + b.arr[i] + carry;
 83         carry = tmp.arr[i] / 10;
 84         tmp.arr[i] = tmp.arr[i] % 10;
 85         ++(tmp.len);
 86     }
 87     if (carry != 0)
 88     {
 89         tmp.arr[tmp.len] = carry;
 90         ++(tmp.len);
 91     }
 92 
 93     return tmp;
 94 }
 95 
 96 node Cmp(node a, node b)
 97 {
 98     if (a.len < b.len)
 99     {
100         return b;
101     }
102     if (a.len > b.len)
103     {
104         return a;
105     }
106 
107     for (int i = a.len - 1; i >= 0; --i)
108     {
109         if (a.arr[i] == b.arr[i]) continue;
110         if (a.arr[i] > b.arr[i])
111         {
112             return a;
113         }
114         else {
115             return b;
116         }
117     }
118     return a;
119 }
120 
121 
122 int main() 
123 {
124     node ans;
125     cin >> n >> m;
126     for (int tn = 0; tn < n; ++tn) 
127     {
128         node dp[MaxN][MaxN];
129         for (int tm = 0; tm < m; ++tm)
130         {
131             cin >> arr[tm];
132             // 初始化:dp[i][i] = (arr[i]<<1)
133             int tmp = (arr[tm] << 1);
134             // 不用while循环,防止 tmp=0
135             do
136             {
137                 dp[tm][tm].arr[dp[tm][tm].len] = tmp % 10;
138                 ++(dp[tm][tm].len);
139                 tmp /= 10;
140             } while (tmp);
141         }
142         for (int k = 1; k < m; ++k) 
143         {
144             for (int i = 0; (i + k) < m; ++i)
145             {
146                 /*node tmp1 = Add(dp[i + 1][i + k], arr[i]);
147                 node tmp2 = Mul(Add(dp[i + 1][i + k], arr[i]));*/
148                 dp[i][i + k] = Mul(Cmp(Add(dp[i + 1][i + k], arr[i]), Add(dp[i][i + k - 1], arr[i+k])));
149             }
150         }
151         ans = Add(ans, dp[0][m - 1]);
152     }
153     for (int i = ans.len - 1; i >= 0; --i) 
154     {
155         cout << ans.arr[i];
156     }
157     cout << endl;
158 
159     
160 #ifdef HOME
161     cerr << "Time elapsed: " << clock() / CLOCKS_PER_SEC << " ms" << endl;
162 #endif
163     return 0;
164 }

 
原文地址:https://www.cnblogs.com/shijianming/p/4933280.html