题意:
给你一个n*m的矩阵,在每一行矩阵的两头单独取数,问最终获得的数的总和的最大值。
思路:
对于每行单独区间dp,设dp[st][ed]表示st到ed区间的最大值,因为取数只能从两端取,那么dp[st][ed]可以由dp[st][ed-1]*2+a[i][ed]*2和dp[st+1][ed]*2+a[i][st]*2转移得来。
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define endl '\n'
#define pb push_back
#define p push
const int mod = 998244353;
__int128 a[110][110];
__int128 dp[100][100];
__int128 qpow(__int128 aa,__int128 bb)
{
__int128 res = 1;
while(bb>0)
{
if(bb&1)res*=aa;
aa*=aa;
bb>>=1;
}
return res;
}
void print(__int128 x)
{
vector<int>ans;
while(x)
{
ans.pb(x%10);
x/=10;
}
for(int i = ans.size()-1; i >= 0; i--)cout<<ans[i];
}
int main()
{
ll n,m;
cin>>n>>m;
for(int i = 1; i <= n; i++)
{
for(int j = 1; j <= m; j++)
{
ll op;
cin>>op;
a[i][j] = op;
}
}
__int128 ans = 0;
for(int i = 1; i <= n; i++)
{
__int128 maxx = 0;
memset(dp,0,sizeof(dp));
// for(int j = 1; j <= m; j++)
// dp[j][j] = a[i][j]*2;
for(int len = 1; len <= m; len++)
{
for(int st = 1; st+len-1 <= m; st++)
{
int ed = st+len-1;
dp[st][ed] = max(dp[st][ed-1]*2+a[i][ed]*2, dp[st+1][ed]*2+a[i][st]*2);
// print(dp[st][ed]);
// cout<<endl;
}
}
ans+=dp[1][m];
}
if(ans==0)cout<<0<<endl;
// cout<<ans<<endl;
print(ans);
}