soj 1488. 矩阵取数游戏

本文深入探讨了一种将高精度运算与动态规划相结合的算法应用实例,详细解释了其核心思路和实现过程,通过逆向分析方法逐步扩展到多个数的处理,最终得出最大可能值。同时,文章引入了高精度运算的基本概念,如加法、乘法和比较大小等操作,并通过代码实例展示了具体实现。此外,还特别强调了高精度运算在解决实际问题中的重要性和实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意太清楚不过了。

思路:

如果不考虑高精度的问题就是一个很简单的逆向分析的问题,之前有过这样的一个题目的分析。就是先确定最后一个数,再扩展到两个,三个,...,m个数。f[X][Y]记录最后取a[X]到a[Y]时能得到的最大的数。递推方程就是:f[i][j] = max(f[i][j-1] + a[j]*pow,  f[i+1][j] + a[i]*pow),其中pow是当时所需要乘的数。

再把高精度加进去即可。。。高精度只要加法,乘以小整数和比较大小。。。

#include <iostream>
#include <cstring>
using namespace std;
#define N 85
#define MAXL 50
int r, c, arr[N];
class BigInt
{
public:
	int data[MAXL];
	BigInt()
	{
		memset(data, 0, sizeof(data));
		data[0] = 1;
	}
	BigInt(const string &s)
	{
		memset(data, 0, sizeof(data));
		data[0] = s.length();
		for (int i = 1; i <= data[0]; ++ i)
			data[i] = s[data[0]-i] - '0';
	}
	BigInt operator = (const BigInt &ob)
	{
		memcpy(data, ob.data, sizeof(data));
		return *this;
	}
	BigInt operator + (const BigInt &ot)
	{
		BigInt sum;
		sum.data[0] = data[0]>ot.data[0] ? data[0] : ot.data[0];
		int i;
		for (i = 1; i <= sum.data[0]; ++ i)
		{
			sum.data[i] += data[i] + ot.data[i];
			sum.data[i+1] += sum.data[i] / 10;
			sum.data[i] %= 10;
		}
		while (sum.data[i] != 0)
		{
			sum.data[i+1] += sum.data[i] / 10;
			sum.data[i] %= 10;
			i ++;
		}
		sum.data[0] = i - 1;
		while(sum.data[sum.data[0]] == 0 && sum.data[0] > 1)
			sum.data[0] -= 1;
		return sum;
	}
	BigInt operator * (const int n)
	{
		BigInt product;
		int i;
		for (i = 1; i <= data[0]; ++ i)
		{
			product.data[i] += data[i] * n;
			product.data[i+1] += product.data[i] / 10;
			product.data[i] %= 10;
		}
		while (product.data[i] != 0)
		{
			product.data[i+1] += product.data[i] / 10;
			product.data[i] %= 10;
			i ++;
		}
		product.data[0] = i - 1;
		while(product.data[product.data[0]] == 0 && product.data[0] > 1)
			product.data[0] -= 1;
		return product;
	}
	bool operator < (const BigInt &ob)
	{
		if (data[0] != ob.data[0]) return data[0] < ob.data[0];
		for (int i = data[0]; i >= 1; -- i)
			if (data[i] != ob.data[i]) return data[i] < ob.data[i];
		return false;
	}
	friend ostream& operator << (ostream &os, BigInt &ob)
	{
		for (int i = ob.data[0]; i >= 1; -- i)
			os << ob.data[i];
		return os;
	}
	friend istream& operator >> (istream &is, BigInt &ob)
	{
		string s;
		is >> s;
		ob = BigInt(s);
		return is;
	}
};
BigInt ans, pow2[N], t1, t2;
BigInt f[N][N];
void init()
{
	pow2[0] = BigInt("1");
	for (int i = 1; i < N; ++ i)
		pow2[i] = pow2[i-1] * 2;
}
int main()
{
	bool start = true;
	init();
	while (cin >> r >> c)
	{
		if (start) start = false;
		else cout << endl;
		ans = BigInt();
		while (r --)
		{
			for (int i = 1; i <= c; ++ i)
			{
				cin >> arr[i];
				f[i][i] = pow2[c] * arr[i];
			}
			for (int i = 2; i <= c; ++ i)
			{
				for (int j = 1; j <= c-i+1; ++ j)
				{
					t1 = f[j][j+i-2] + pow2[c-i+1]*arr[j+i-1];
					t2 = f[j+1][j+i-1] + pow2[c-i+1]*arr[j];
					if (t1 < t2) f[j][j+i-1] = t2;
					else f[j][j+i-1] = t1;
				}
			}
			ans = ans + f[1][c];
		}
		cout << ans << endl;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值