uva10755

题意是求最大子立方体的和

Sol

降维 + 二维前缀和。

即是对于某一维,比如x,我们把(y,z)的二维前缀和保存在x里面。

s[i][j][k] = s[i][j - 1][k] + s[i][j][k - 1] - s[i][j - 1][k - 1] + g[i][j][k];

也就是这一句。

然后整一个O(n5)的枚举,对x进行dp。(这样实际上也可以理解为用三维表示了一个立方体)

for (ll i = 0; i <= y; i++)
        for (ll j = i + 1; j <= y; j++)
            for (ll p = 0; p <= z; p++)
                for (ll q = p + 1; q <= z; q++)
                {
                    memset(dp, 0, sizeof 0);//最坏的情况是一个都不选。
                    for (ll k = 1; k <= x; k++)
                    {
                        ll t = count(i, j, p, q, k);
                        dp[k] = max(dp[k - 1] + t, t); 
                        ans = max(ans, dp[k]);
                    }
                }

本题还有一个坑点,不要把inf开太小,对于最大数小于231的题目,inf要开到1e10。

因为这个WA,就太亏了。

#include <cstdio>
#include <cstring>
#include <algorithm>
#define ll long long
using namespace std;

const ll maxn = 25, inf = 1e10;

ll t, x ,y, z;

ll s[maxn][maxn][maxn], g[maxn][maxn][maxn], dp[maxn];

ll count(ll i, ll j, ll p, ll q, ll k)
{
    return s[k][j][q] - s[k][i][q] - s[k][j][p] + s[k][i][p];
}

void solve()
{
    scanf("%lld%lld%lld", &x, &y, &z);
    memset(s, 0, sizeof s);
    for (ll i = 1; i <= x; i++)
        for (ll j = 1; j <= y; j++)
            for (ll k = 1; k <= z; k++)
            {
                scanf("%lld", &g[i][j][k]);
                s[i][j][k] = s[i][j - 1][k] + s[i][j][k - 1] - s[i][j - 1][k - 1] + g[i][j][k];
            }
    ll ans = -inf;
    for (ll i = 0; i <= y; i++)
        for (ll j = i + 1; j <= y; j++)
            for (ll p = 0; p <= z; p++)
                for (ll q = p + 1; q <= z; q++)
                {
                    memset(dp, 0, sizeof 0);//最坏的情况是一个都不选。
                    for (ll k = 1; k <= x; k++)
                    {
                        ll t = count(i, j, p, q, k);
                        dp[k] = max(dp[k - 1] + t, t); 
                        ans = max(ans, dp[k]);
                    }
                }
    printf("%lld\n", ans);
    if (t) printf("\n");
}

int main()
{
//    freopen("uva10755.in","r",stdin);
    scanf("%lld", &t);
    while (t--) solve();
    return 0;
}

 

posted @ 2017-10-21 12:07  yohanlong  阅读(164)  评论(0编辑  收藏  举报