洛谷1005 矩阵取数游戏

  传送门

思路:

  首先当然是每行单独处理 再把答案相加

  我们发现如果知道还没有取数的区间长度 就知道现在取了多少个数

  也就是说我们可以知道现在要取的数做贡献要乘的系数

  每次取数只能在左右两端取 所以转移的时候在这两种情况中取min即可

  记搜会很方便啊

CODE:

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 using namespace std;
 5 int read()
 6 {
 7     int x=0,y=1;;char ch;
 8     ch=getchar();
 9     while(ch<'0'||ch>'9') {if(ch=='-') y=-1;ch=getchar();}
10     while(ch>='0'&&ch<='9') {x=x*10+ch-'0';ch=getchar();}
11     return x*y;
12 }
13 __int128 n,m,a[100],ans;
14 __int128 f[100][100],p[100];
15 __int128 dfs(int l,int r) //从l到r的区间
16 {
17     if(f[l][r]!=-1) return f[l][r];
18     if(l==r) return p[m]*a[l];
19     f[l][r]=max(a[l]*p[(m-r+l)]+dfs(l+1,r),a[r]*p[m-r+l]+dfs(l,r-1));
20     return f[l][r];
21 } 
22 void print(__int128 x)
23 {
24     if(!x) return;
25     if(x) print(x/10);
26     putchar(x%10+'0');
27 }
28 int main()
29 {
30     n=read();m=read();
31     p[1]=2;
32     for(int i=2;i<=m;i++) p[i]=p[i-1]<<1;
33     for(int i=1;i<=n;i++)
34     {
35         memset(f,-1,sizeof(f));
36         for(int j=1;j<=m;j++) a[j]=read();
37         ans+=dfs(1,m);
38     }
39     if(ans==0) cout<<"0";
40     print(ans);
41     return 0;
42 }
View Code
扫描二维码关注公众号,回复: 5130891 查看本文章

猜你喜欢

转载自www.cnblogs.com/forward777/p/10339855.html