P1005 矩阵取数游戏

P1005 矩阵取数游戏

  •  区间dp,每一行单独处理,因为数据范围比较大所以要用高精或者__int128。
  • 对于每行来说,用f[i,j]表示取完当前行的第i~j个数的最大值,则f[i,j]=max(f[i+1,j]+a[i]*2^(m-(i-j+1)),f[i,j+1]+a[j]*2^(m-(i-j+1))
  • 初始化:f[i,i]=a[i]*2^m(最后一个),目标:f[1,m]
  • 打印时记得加特判ans=0

代码:

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <cctype>
 5 #include <iostream>
 6 using namespace std;
 7 
 8 #define res register int
 9 inline int read()
10 {
11     int x(0),f(1); char ch;
12     while(!isdigit(ch=getchar()))  if(ch=='-') f=-1;
13     while(isdigit(ch)) x=(x<<1)+(x<<3)+ch-'0',ch=getchar();
14     return f*x;
15 }
16 
17 const int N=80+5;
18 int n,m;
19 __int128 f[N][N],ans,a[N],p[N];
20 
21 inline void print(__int128 x)
22 {
23     if(!x) return;
24     print(x/10);
25     putchar(x%10+'0');
26 }
27 
28 int main()
29 {
30     n=read(); m=read();
31     p[0]=1; 
32     for(res i=1 ; i<=m ; i++) p[i]=p[i-1]*2;
33     for(res i=1 ; i<=n ; i++)
34     {
35         memset(f,0,sizeof(f));
36         for(res j=1 ; j<=m ; j++) a[j]=read(),f[j][j]=a[j]*p[m];
37         for(res len=2 ; len<=m ; len++)
38         {
39             for(res l=1 ; l<=m-len+1 ; l++)
40             {
41                 int r=l+len-1;
42                 f[l][r]=max(f[l+1][r]+a[l]*p[m-len+1],f[l][r-1]+a[r]*p[m-len+1]);
43             }
44             ans+=f[1][m];
45         }
46     }
47     if(!ans) printf("0");
48     else print(ans);
49     return 0;
50 }
View Code
原文地址:https://www.cnblogs.com/wmq12138/p/10365623.html