P1005 [NOIP2007 提高组] 矩阵取数游戏

传送门

题意:

给你一个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);
}
 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值