P1005 矩阵取数

题目链接

看完题可能第一时间并没有清晰的思路。让我们一步一步的来考虑这道题目。

题目中描述操作为每次从所有的行中选取,这样做有些麻烦。仔细思考一下可以发现行与行之间互不干涉,所以我们可以对每行操作到底,最后统计答案。

每行怎么选取当然难不倒聪明的oier了,设f[i][j]表示某行从第i位到第j位的最优答案。

转移如下

   f[i][j]=max((f[i+1][j]+b[i]<<1),(f[i][j-1]+b[j]<<1));


到此,这道题目就做完了。

 1 #include<cstring>
 2 #include<iostream>
 3 #include<cctype>
 4 #include<cstdio>
 5 #include<algorithm>
 6 #define ll __int128_t 
 7 using namespace std;
 8 inline ll read()
 9 {
10     register ll X=0;register char ch=0;
11     for(;!isdigit(ch);ch=getchar());
12     for(;isdigit(ch);ch=getchar()) X=(X<<3)+(X<<1)+(ll)ch-'0';
13     return X;
14 }
15 inline void write(ll x)
16 {
17      if(x>9) write(x/10);
18      putchar(x%10+'0');
19 }
20 int n,m;
21 ll a[81][81],f[81][81],ans;
22 ll work(ll b[])
23 {
24     memset(f,0,sizeof(f));
25     for(int l=0;l<=m;l++)
26         for(int i=1;i+l<=m;i++)
27         {
28             int j=i+l;
29             f[i][j]=max((f[i+1][j]+b[i]<<1),(f[i][j-1]+b[j]<<1));
30         }
31     return f[1][m];
32 }
33 int main()
34 {
35     n=read(),m=read();
36     for(int i=1;i<=n;i++)
37         for(int j=1;j<=m;j++)
38             a[i][j]=read();
39     for(int i=1;i<=n;i++)
40         ans+=work(a[i]);
41     write(ans);
42 }
View Code

需要注意的是,这道题目由于数据范围过大需要使用高精度运算,然而在洛谷上是可以用_int128水过去的。

posted @ 2018-08-30 10:42  _hcy_a  阅读(155)  评论(0编辑  收藏  举报