题目链接:https://www.luogu.org/problemnew/show/P1004

题目描述

设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放

人数字0。如下图所示(见样例):

A
0 0 0 0 0 0 0 0
0 0 13 0 0 6 0 0
0 0 0 0 7 0 0 0
0 0 0 14 0 0 0 0
0 21 0 0 0 4 0 0
0 0 15 0 0 0 0 0
0 14 0 0 0 0 0 0
0 0 0 0 0 0 0 0
. B

某人从图的左上角的A点出发,可以向下行走,也可以向右走,直到到达右下角的B

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

此人从A点到B点共走两次,试找出2条这样的路径,使得取得的数之和为最大。

输入输出格式

输入格式:

输入的第一行为一个整数N(表示N*N的方格图),接下来的每行有三个整数,前两个

表示位置,第三个数为该位置上所放的数。一行单独的0表示输入结束。

输出格式:

只需输出一个整数,表示2条路径上取得的最大的和。

输入输出样例

输入样例#1: 

8
2 3 13
2 6 6
3 5 7
4 4 14
5 2 21
5 6 4
6 3 15
7 2 14
0 0 0
输出样例#1: 

67
四维dp数组:
将这两条路线看成是两个人同时走不同的路线,开一个四维dp数组记录下这两人的坐标。
#include <bits/stdc++.h>
using namespace std;
int mapp[][];
int dp[][][][]; //两条路线,既可以假设为两个人同时走不同的路线,dp[i][j][k][l]表示这两个人走到该点取数的最大和
//mapp[i][j]为第一人的坐标,mapp[k][l]为第二人的坐标
int main()
{
int n, x, y, m;
cin >>n>> x >> y >> m;
while (x != || y != || m != )
{
mapp[x][y] = m;
cin >> x >> y >> m;
}
for (int i = ; i <= n; i++)
for (int j = ; j <= n; j++)
for(int k=;k<=n;k++)
for (int l = ; l <= n; l++)
{ //由于任意一点mapp[i][j]只能由mapp[i-1][j],或者mapp[i][j-1]达到,且控制这两个人的步数相同(即i和j中有且仅有一个数-1,k和l中有且仅有一个数-1),所以总共由4种情况要考虑
dp[i][j][k][l] = max(max(dp[i][j-][k-][l], dp[i][j - ][k][l-]), max(dp[i-][j][k - ][l], dp[i-][j][k][l - ])) + mapp[i][j] + mapp[k][l];
if (i == k && j == l)dp[i][j][k][l] -= mapp[i][j]; //由于方格中的数只能取一次,所以如果这两个人走到了同一个点,mapp[i][j]只能加一次
}
cout << dp[n][n][n][n];
return ;
}
接下来是对以上四维dp的优化,三维dp数组也能解决

定义d[i][j][k]为走了i步,路径a向下走了j步,路径b向下了k步,取数和的最大值;

此时(i-j),(i-k)就是a与b此时到达点的纵坐标;其它的地方都与四维dp类似

#include <bits/stdc++.h>
using namespace std;
int mapp[][];
int f[][][];
int n, x, y, z;
int main()
{
scanf("%d", &n);
memset(f, , sizeof(f));
memset(mapp, , sizeof(mapp));
while (scanf("%d%d%d", &x, &y, &z), x || y || z)
mapp[x][y] = z;
for (int k = ; k <= * n - ; k++)
{
for (int i = ; i <= min(k, n); i++)
{
for (int j = ; j <= min(n, k); j++)
{
f[k][i][j] = max(max(f[k - ][i][j], f[k - ][i][j - ]), max(f[k - ][i - ][j], f[k - ][i - ][j - ]));
if (i == j) f[k][i][j] += mapp[i][k - j + ];
else f[k][i][j] += mapp[i][k - i + ] + mapp[j][k - j + ];
}
}
}
printf("%d\n", f[ * n - ][n][n]);
return ;
}
2018-05-15

洛谷 P1004 方格取数 【多进程dp】的更多相关文章

  1. 洛谷P1004 方格取数-四维DP

    题目描述 设有 N \times NN×N 的方格图 (N \le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 .如下图所示(见样例): A 0 0 0 0 0 ...

  2. 洛谷 - P1004 - 方格取数 - 简单dp

    https://www.luogu.org/problemnew/show/P1004 这道题分类到简单dp但是感觉一点都不简单……这种做两次的dp真的不是很懂怎么写.假如是贪心做两次,感觉又不能证明 ...

  3. 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏

    P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...

  4. 洛谷 P1004 方格取数 题解

    P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...

  5. 洛谷P1004 方格取数

    网络流大法吼 不想用DP的我选择了用网络流-- 建模方法: 从源点向(1,1)连一条容量为2(走两次),费用为0的边 从(n,n)向汇点连一条容量为2,费用为0的边 每个方格向右边和下边的方格连一条容 ...

  6. 洛谷 P1004 方格取数 【多线程DP/四维DP/】

    题目描述(https://www.luogu.org/problemnew/show/1004) 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0. ...

  7. 洛谷 P1004 方格取数

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...

  8. 【动态规划】洛谷P1004方格取数

    题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...

  9. 四维动规 洛谷P1004方格取数

    分析:这个题因为数据量非常小,可以直接用四维的DP数组 dp[i][j][k][l]表示第一个人走到位置(i,j),第二个人走到位置[k][l]时所取的数的最大和 状态转移方程可以轻松得出为:dp[i ...

随机推荐

  1. POJ 1061 青蛙的约会 (扩展欧几里得算法)

    题目链接 Description 两只青蛙在网上相识了,它们聊得很开心,于是觉得很有必要见一面.它们很高兴地发现它们住在同一条纬度线上,于是它们约定各自朝西跳,直到碰面为止.可是它们出发之前忘记了一件 ...

  2. Javascript - 学习总目录

    Javascript - 操作符 Javascript - 数据类型 Javascrip - 语句 Javascript - 函数 Javascript - 预编译与函数词法作用域 Javascrip ...

  3. Jquery对当前日期的操作(格式化当前日期)

    // 对Date的扩展,将 Date 转化为指定格式的String // 月(M).日(d).小时(h).分(m).秒(s).季度(q) 可以用 1-2 个占位符, // 年(y)可以用 1-4 个占 ...

  4. swift中闭包的学习。

    在swift中的闭包等同于OC中的block,它的用途就是在于可以包装一段代码在必要的时候进行调用. 闭包定义:  {(类型列表) -> 返回值 in // 多条swift语句 // 执行代码 ...

  5. jQuery的end() 方法

    定义和用法 end() 方法结束当前链条中的最近的筛选操作,并将匹配元素集还原为之前的状态. 语法 .end() 详细说明 大多数 jQuery 的遍历方法会操作一个 jQuery 对象实例,并生成一 ...

  6. centos6安装python3.6.4

    安装Python依赖包: [root@Python src]# yum install zlib-devel bzip2-devel openssl-devel ncurses-devel sqlit ...

  7. C++:__stdcall详解

    原文地址:http://www.cnblogs.com/songfeixiang/p/3733661.html 对_stdcall 的理解(上)在C语言中,假设我们有这样的一个函数:int funct ...

  8. Python-百度经纬度转高德经纬度

    import math def bdToGaoDe(lon,lat): """ 百度坐标转高德坐标 :param lon: :param lat: :return: &q ...

  9. 安装cactiez v11对windows和linux系统进行监控

    日常运维中我们需要对服务器的流量.CPU占用.硬盘使用及内存.磁盘IP等进行监控和了解,cactiez是一款基于centos6.4定制安装了常用监控软件的系统,安装简单,功能强大很适合快速部署监控系统 ...

  10. sipML5聊天功能实现

    一.环境说明:在阅读sipML5的API文档时,发现它具有聊天的功能,于是在sipML5的源码中进行设定,实现了注册之后可以英文聊天(中文聊天需要在FreeSWITCh中进行设定). 二.具体配置: ...