luogu P1005 矩阵取数游戏

传送门

我再做高精就****

基础dp

然后直接*2^80就暗示高精

然后40min写完之后就一直不过样例...

最后发现自己比较大小从右往左比较的...

窒息 赶紧更自己的板子 

本身来讲记忆化搜索更适合状压dp和区间dp 一类树形dp也非常好用

所以这题就记搜(反正都没啥代码难度)

哦除了高精

算了上代码

Time cost:75min

Code:

  1 #include<cstdio>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<queue>
  6 #include<vector>
  7 #include<iostream>
  8 #include<iomanip>
  9 #define itn int
 10 #define ms(a,b) memset(a,b,sizeof a)
 11 #define rep(i,a,n) for(int i = a;i <= n;i++)
 12 #define per(i,n,a) for(int i = n;i >= a;i--)
 13 #define inf 2147483647
 14 using namespace std;
 15 typedef long long ll;
 16 ll read() {
 17     ll as = 0,fu = 1;
 18     char c = getchar();
 19     while(c < '0' || c > '9') {
 20         if(c == '-') fu = -1;
 21         c = getchar();
 22     }
 23     while(c >= '0' && c <= '9') {
 24         as = as * 10 + c - '0';
 25         c = getchar();
 26     }
 27     return as * fu;
 28 }
 29 
 30 struct Big {
 31     const static int N = 105;
 32     int a[N];
 33     bool flag;
 34     Big(){ms(a,0),flag = 0;}
 35     Big( ll x ){
 36         ms(a,0),flag = 0;
 37         if(x == 0) return;
 38         flag = (x < 0);
 39         x = max(x,-x);
 40         while(x) a[++a[0]] = x%10,x/=10;
 41         clr0();
 42     }
 43     void read() {
 44         ms(a,0),flag = 0;
 45         char s[N];
 46         scanf("%s",s+1);
 47         a[0] = strlen(s+1);
 48         if(s[1] == '-') a[0]--,flag = 1;
 49         rep(i,1,a[0]) a[i] = s[a[0] - i + flag + 1] - '0';
 50         clr0();
 51     }
 52     void clr0() {
 53         while(a[0] && a[a[0]] == 0) a[0]--;
 54         while(a[0] < 0) a[0]++;
 55         if(a[0] == 0) flag = 0;
 56     }
 57     void print() {
 58         clr0();
 59         if(!a[0]) return void(puts("0"));
 60         if(flag) putchar('-');
 61         per(i,a[0],1) putchar(a[i] + '0');
 62         putchar('
');
 63     }
 64     //clr0 before use
 65     bool operator < (const Big &o) const {
 66         if(o.a[0] == 0) return flag;
 67         if(a[0] == 0) return !o.flag;
 68         if(flag ^ o.flag) return flag;
 69         if(a[0] ^ o.a[0]) return ((a[0] < o.a[0]) ^ flag);
 70         per(i,a[0],1) {
 71             if(a[i] > o.a[i]) return flag;
 72             if(a[i] < o.a[i]) return !flag;
 73         }
 74         return 0;
 75     }
 76     bool operator == (const Big &o) const {
 77         Big r = *this;
 78         return !(r < o || o < r);
 79     }
 80     //保证同号
 81     Big operator + (const Big &o) const {
 82         if(a[0] == 0) return o;
 83         if(o.a[0] == 0) return *this;
 84         if(flag ^ o.flag) {
 85             Big x = *this,y = o;
 86             if(x.flag) {
 87                 x.flag = 0;
 88                 return y - x;
 89             }
 90             else {
 91                 y.flag = 0;
 92                 return x - y;
 93             }
 94         }
 95         Big ans;
 96         ms(ans.a,0);
 97         ans.a[0] = max(a[0],o.a[0]),ans.flag = flag;
 98         rep(i,1,ans.a[0]) {
 99             ans.a[i] += a[i] + o.a[i];
100             if(i == ans.a[0] && ans.a[i] >= 10) {
101                 ans.a[0]++;
102             }
103             ans.a[i+1] += ans.a[i] / 10;
104             ans.a[i] %= 10;
105         }
106         return ans;
107     }
108     //保证同号
109     Big operator - (const Big &o) const {
110         Big x = *this;
111         Big y = o;
112         if(flag ^ o.flag) {
113             y.flag ^= 1;
114             return x + y;
115         }
116         Big ans;
117         ms(ans.a,0);
118         ans.a[0] = ans.flag = 0;
119         ans.flag = flag;
120         x.flag = y.flag = 0;
121         if(x == y) return ans;
122         if(x < y) swap(x,y),ans.flag ^= 1;
123         rep(i,1,x.a[0]) {
124             if(x.a[i] < y.a[i]) x.a[i] += 10,x.a[i+1]--;
125             ans.a[i] = x.a[i] - y.a[i];
126         }
127         ans.a[0] = x.a[0];
128         ans.clr0();
129         return ans;
130     }
131     //O(n^2) 高精乘
132     Big operator * (const Big &o) const {
133         if(a[0] == 0) return *this;
134         if(o.a[0] == 0) return o;
135         Big ans;
136         ms(ans.a,0);
137         ans.a[0] = a[0] + o.a[0],ans.flag = o.flag ^ flag;
138         rep(i,1,a[0]) rep(j,1,o.a[0])
139             ans.a[i+j-1] += a[i] * o.a[j];
140         rep(i,1,ans.a[0]) {
141             if(i == ans.a[0] && ans.a[i] >= 10) ans.a[0]++;
142             ans.a[i+1] += ans.a[i] / 10;
143             ans.a[i] %= 10;
144         }
145         return ans;
146     }
147 };
148 //head
149 int n,m;
150 Big zero = Big(0ll);
151 Big two = Big(2ll);
152 Big dp[85][85],ans;
153 ll v[85][85];
154 
155 void tst() {
156     Big x,y;
157     while(1) {
158         x.read(),y.read();
159         if(x < y) x.print(),putchar('<'),y.print();
160         else if(y < x) x.print(),putchar('>'),y.print();
161         else putchar('=');
162     }
163 }
164 
165 Big max(const Big &x,const Big &y) {
166     if(x < y) return y;
167     return x;
168 }
169 
170 Big dfs(int x,int l,int r) {
171     if(!(dp[l][r] == zero)) return dp[l][r];
172     if(l == r) return Big(v[x][r]*2);
173     Big tmp1,tmp2;
174     tmp1 = ((dfs(x,l+1,r) * two) + Big(v[x][l]*2ll));
175     tmp2 = ((dfs(x,l,r-1) * two) + Big(v[x][r]*2ll));
176     return dp[l][r] = max(tmp1,tmp2);
177 }
178 
179 int main() {
180 //    tst();
181     n = read(),m = read();
182     ans = zero;
183     rep(i,1,n) rep(j,1,m) v[i][j] = read();
184     rep(i,1,n) {
185         rep(l,1,m) rep(r,1,m) dp[l][r] = zero;
186         Big tmp = dfs(i,1,m);
187         ans = ans + tmp;
188     }
189     ans.print();
190     return 0;
191 }
View Code

 

> 别忘了 总有人在等着你
原文地址:https://www.cnblogs.com/yuyanjiaB/p/9901836.html