• neu1458 方格取数 dp解法


    题意:

    有N * N个格子,每一个格子里有正数或者0,从最左上角往最右下角走,仅仅能向下和向右,一共走两次(即从左上角走到右下角走两趟),把全部经过的格子的数加起来,求最大值SUM,且两次假设经过同一个格子,则最后总和SUM中该格子的计数仅仅加一次。


    走两次,所以状态表示要同一时候表示两次路径。dp[i][j][k][l] 表示第一次走到i,  j,第二次走到k, l得到的最大值,这里i + j == k + l

    事实上第四维是能够通过前三维算出来的,所以能够去掉

    那么dp[i][j][k] 能够通过四种状态转移,(i, j - 1, k)  (i,  j - 1, k - 1) (i - 1,  j,  k) (i - 1, j, k - 1)即两次都能够选择是从上或者左边移动过来

    由于i + j == k + l,所以 i + j - k是l 的位置,1 <= l <= n,即 i + j <= k + n && i + j >= k + 1 


    #include <cstdio>
    #include <ctime>
    #include <cstdlib>
    #include <cstring>
    #include <queue>
    #include <string>
    #include <set>
    #include <stack>
    #include <map>
    #include <cmath>
    #include <vector>
    #include <iostream>
    #include <algorithm>
    #include <bitset>
    #include <fstream>
    using namespace std;
    //LOOP
    #define FF(i, a, b) for(int i = (a); i < (b); ++i)
    #define FE(i, a, b) for(int i = (a); i <= (b); ++i)
    #define FED(i, b, a) for(int i = (b); i>= (a); --i)
    #define REP(i, N) for(int i = 0; i < (N); ++i)
    #define CLR(A,value) memset(A,value,sizeof(A))
    #define FC(it, c) for(__typeof((c).begin()) it = (c).begin(); it != (c).end(); it++)
    //OTHER
    #define SZ(V) (int)V.size()
    #define PB push_back
    #define MP make_pair
    #define all(x) (x).begin(),(x).end()
    //INPUT
    #define RI(n) scanf("%d", &n)
    #define RII(n, m) scanf("%d%d", &n, &m)
    #define RIII(n, m, k) scanf("%d%d%d", &n, &m, &k)
    #define RIV(n, m, k, p) scanf("%d%d%d%d", &n, &m, &k, &p)
    #define RV(n, m, k, p, q) scanf("%d%d%d%d%d", &n, &m, &k, &p, &q)
    #define RS(s) scanf("%s", s)
    //OUTPUT
    #define WI(n) printf("%d
    ", n)
    #define WS(n) printf("%s
    ", n)
    //debug
    //#define online_judge
    #ifndef online_judge
    #define dt(a)  << (#a) << "=" << a << " "
    #define debugI(a) cout dt(a) << endl
    #define debugII(a, b) cout dt(a) dt(b) << endl
    #define debugIII(a, b, c) cout dt(a) dt(b) dt(c) << endl
    #define debugIV(a, b, c, d) cout dt(a) dt(b) dt(c) dt(d) << endl
    #define debugV(a, b, c, d, e) cout dt(a) dt(b) dt(c) dt(d) dt(e) << endl
    #else
    #define debugI(v)
    #define debugII(a, b)
    #define debugIII(a, b, c)
    #define debugIV(a, b, c, d)
    #endif
    
    #define sqr(x) (x) * (x)
    typedef long long LL;
    typedef unsigned long long ULL;
    typedef vector <int> VI;
    const double eps = 1e-9;
    const int MOD = 1000000007;
    const double PI = acos(-1.0);
    const int INF = 0x3f3f3f3f;
    const int maxn = 105;
    
    int dp[maxn][maxn][maxn];
    int w[maxn][maxn];
    
    int main()
    {
        //freopen("0.txt", "r", stdin);
        int n;
        while (~RI(n))
        {
            FE(i, 1, n) FE(j, 1, n) RI(w[i][j]);
            CLR(dp, 0);
            FE(i, 1, n)
            {
                FE(j, 1, n)
                {
                    FE(k, 1, n)
                        if (i + j >= k + 1 && i + j <= k + n)
                        {
                            int t = max(dp[i][j - 1][k - 1], dp[i][j - 1][k] )
                                        + (k == i ? w[i][j] : w[i][j] + w[k][i + j - k]);
                            if (t > dp[i][j][k])
                                dp[i][j][k] = t;
                            t = max(dp[i - 1][j][k - 1], dp[i - 1][j][k])
                                    + (k == i ? w[i][j] : w[i][j] + w[k][i + j - k]);
                            if (t > dp[i][j][k])
                                dp[i][j][k] = t;
                        }
                }
            }
            WI(dp[n][n][n]);
        }
        return 0;
    }
    
    


  • 相关阅读:
    Android ListView 的布局图标大小设置
    Android BaseAdapter 类 重写模版
    Fabric 介绍
    CentOS yum安装mysql
    JavaStringBuffer类常用方法简介
    Java流的简单使用:读取文件、写入文件(面试题:删除注释代码)
    Android数据库详解之二:数据库用法介绍
    JavaString类的方法及说明
    Android图像识别项目OpenCV(1):技术选型以及NDK搭建
    JDK(6u25)安装及相关知识
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4181150.html
Copyright © 2020-2023  润新知