zoukankan      html  css  js  c++  java
  • 洛谷1005 矩阵取数游戏

    原题链接

    由于每一行之间没有干扰,所以可以一行一行(DP)过去。
    (f[i][j])表示区间([1,i)cup (j, m])被取所取得的最大值,则有转移方程:

    (qquadqquad f[i][j] = max{f[i][j], max{f[i - 1][j] + 2^{m - (j - i + 1)} imes a[i - 1], f[i][j + 1] + 2 ^ {m - (j - i + 1)} imes a[j + 1] } })

    则每一行取得的最大值为:

    (qquadqquad maxlimits_{i = 1} ^ m { f[i][i] + 2 ^ m imes a[i] })

    因为数据大,需要使用高精(懒得话可以使用(int128))。

    #include<cstdio>
    #include<cstring>
    using namespace std;
    typedef long long ll;
    const int N = 85;
    const int base = 1e8;
    int a[N];
    struct bigint {
    	ll s[N];
    	int l;
    	bigint()
    	{
    		memset(s, 0, sizeof(s));
    		l = 0;
    	}
    	bigint operator = (const int &b)
    	{
    		bigint c;
    		int x = b;
    		do
    		{
    			c.s[++c.l] = x % base;
    			x /= base;
    		} while (x > 0);
    		return *this = c;
    	}
    	bigint operator + (const bigint &b)
    	{
    		bigint c;
    		ll x = 0;
    		int i, k = l < b.l ? b.l : l;
    		c.l = k;
    		for (i = 1; i <= k; i++)
    		{
    			x += s[i] + b.s[i];
    			c.s[i] = x % base;
    			x /= base;
    		}
    		if (x > 0)
    			c.s[++c.l] = x;
    		return c;
    	}
    	bigint operator * (const int &b)
    	{
    		bigint c;
    		ll x = 0;
    		int i;
    		c.l = l;
    		for (i = 1; i <= l; i++)
    		{
    			x += s[i] * b;
    			c.s[i] = x % base;
    			x /= base;
    		}
    		if (x > 0)
    			c.s[++c.l] = x;
    		return c;
    	}
    	bool operator < (const bigint &b) const
    	{
    		if (l ^ b.l)
    			return l < b.l;
    		for (int i = l; i; i--)
    			if (s[i] < b.s[i])
    				return true;
    			else
    				if (s[i] > b.s[i])
    					return false;
    		return false;
    	}
    };
    bigint f[N][N], po[N], s, ma;
    inline int re()
    {
    	int x = 0;
    	char c = getchar();
    	bool p = 0;
    	for (; c < '0' || c > '9'; c = getchar())
    		p |= c == '-';
    	for (; c >= '0' && c <= '9'; c = getchar())
    		x = x * 10 + c - '0';
    	return p ? -x : x;
    }
    inline bigint maxn(bigint x, bigint y)
    {
    	return x < y ? y : x;
    }
    int main()
    {
    	int i, j, n, m;
    	n = re();
    	m = re();
    	s = 0;
    	for (po[0] = i = 1; i <= m; i++)
    		po[i] = po[i - 1] * 2;
    	while (n--)
    	{
    		ma = 0;
    		for (i = 1; i <= m; i++)
    			for (j = 1; j <= m; j++)
    				f[i][j] = 0;
    		for (i = 1; i <= m; i++)
    			a[i] = re();
    		for (i = 1; i <= m; i++)
    			for (j = m; j >= i; j--)
    				f[i][j] = maxn(f[i][j], maxn(f[i - 1][j] + po[m - j + i - 1] * a[i - 1], f[i][j + 1] + po[m - j + i - 1] * a[j + 1]));
    		for (i = 1; i <= m; i++)
    			ma = maxn(ma, f[i][i] + po[m] * a[i]);
    		s = s + ma;
    	}
    	printf("%lld", s.s[s.l]);
    	for (i = s.l - 1; i; i--)
    		printf("%08lld", s.s[i]);
    	return 0;
    }
    
  • 相关阅读:
    PHP常见问题总结
    Java常见问题总结(二)
    C语言常见问题总结
    C#常见问题总结(三)
    C#常见问题总结(二)
    Android常见问题总结(二)
    日期和时间类函数
    Eclipse开发工具介绍
    JavaScript中逻辑运算符的使用
    多路开关模式的switch语句
  • 原文地址:https://www.cnblogs.com/Iowa-Battleship/p/9826832.html
Copyright © 2011-2022 走看看