neu1458 方格取数 dp解法

来源:互联网 发布:背锅侠网络意思 编辑:程序博客网 时间:2024/05/16 07:35

题意:

有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", n)#define WS(n) printf("%s\n", 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;}


1 0
原创粉丝点击