zoukankan      html  css  js  c++  java
  • 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
    ", ans);
        if (t) printf("
    ");
    }
    
    int main()
    {
    //    freopen("uva10755.in","r",stdin);
        scanf("%lld", &t);
        while (t--) solve();
        return 0;
    }
  • 相关阅读:
    图表算法—有向图
    图表算法—无向图
    搜索算法—哈希表
    红黑树的删除
    搜索算法—红黑树
    搜索算法—二叉搜索树
    排序算法—堆排序
    快速排序改进——3区快速排序(3-way quicksort)
    数论——约数:算数基本定理及推论,欧几里得算法
    数论——乘法逆元(快速幂求法)及模运算
  • 原文地址:https://www.cnblogs.com/yohanlong/p/7704366.html
Copyright © 2011-2022 走看看