多线程DP 三取方格数

描述: 

设有N*N的方格图,我们将其中的某些方格填入正整数,而其他的方格中放入0。

某人从图得左上角出发,可以向下走,也可以向右走,直到到达右下角。

在走过的路上,他取走了方格中的数。(取走后方格中数字变为0)

此人从左上角到右下角共走3次,试找出3条路径,使得取得的数总和最大。


输入格式:

第一行:N(4<=N<=20)

接下来一个N*N的矩阵,矩阵中每个元素不超过80,不小于0 

  

输出格式:

一行,表示最大的总和。



样例输入: 

4

1 2 3 4

2 1 3 4

1 2 3 4

1 3 2 4


样例输出: 
 

39

 

#include <iostream>
#include <cstring>
using namespace std;

#define SIZE 30

int DP[SIZE][SIZE][SIZE][SIZE];
int matrix[SIZE][SIZE];

int main(){

    int size;
    int steps;
    int temp;

    memset( DP,     0, sizeof( DP ) );
    memset( matrix, 0, sizeof( matrix ) );

    cin >> size;

    steps = size * 2 - 1;

    for( int raw = 1; raw <= size; ++raw ){
        for( int col = 1; col <= size; ++col ){
            cin >> matrix[raw][col];
        }
    }

    DP[1][1][1][1] = matrix[1][1];

    for( int step = 1; step <= steps; ++step ){
        for( int x1 = 1; x1 <= min( step, size ); ++x1 ){
            for( int x2 = 1; x2 <= min( step, size ); ++x2 ){
                for( int x3 = 1; x3 <= min( step, size ); ++x3 ){

                    temp = matrix[x1][step - x1 + 1] +
                           matrix[x2][step - x2 + 1] +
                           matrix[x3][step - x3 + 1];

                    if( x1 == x2 )
                        temp -= matrix[x2][step - x2 + 1];

                    if( x1 == x3 )
                        temp -= matrix[x3][step - x3 + 1];

                    if( x2 == x3 )
                        temp -= matrix[x3][step - x3 + 1];

                    if( x1 == x2 && x2 == x3 )
                        temp += matrix[x1][step - x1 + 1];

                    for( int i = -1; i <= 0; ++i ){
                        for( int j = -1; j <= 0; ++j ){
                            for( int k = -1; k <= 0; ++k ){
                                DP[step][x1][x2][x3] = max( DP[step][x1][x2][x3],
                                                            DP[step - 1][x1 + i][x2 + j][x3 + k] + temp );
                            }
                        }
                    }
                }
            }
        }
    }

    cout << DP[steps][size][size][size] << endl;

    return 0;

}


  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值