洛谷P1004
洛谷P1004方格取数
题目大意
本题简要意思就是一个人从一个数字矩阵的左上角走到右下角,只能向下和向右走,拿完的数对应位置变成0,并且这个人要走两次,需要计算两次所拿数的最大值
Train of thought
本题和数字三角形十分类似,只不过要走两次,我们可以考虑用dp的方式解决问题
动态规划的关键是状态表示和递推方程
如果我们这里和数字三角形一样采用二维的dp方式,我们还需要找到所有第一次走的解,并且还要保存,然后在第一次解的角度上解析第二次走的收益
如图所示:

如果这样做的话时间复杂度可能是指数级别的,可能会超时
所以我们这里选择利用四维数组储存两次走的状态,f[i][j][k][l]表示第一次走到(k,l),第二次走到(i,j)时所能得到的最大收益。
这里没有区分次序,对于可能出现的重复拿数的问题,我们需要把这个数减去
< if(i == k && j ==l) f[i][j][k][l] -= Square[i][j];>
递推方程显然为max(f[i-1][j][k-1][l],f[i - 1][j][k][l - 1],f[i][j- 1][k- 1][l],f[i][j-1][k][l-1])
也就是< f[i][j][k][l] = max(max(f[i - 1][j][k - 1][l],f[i - 1][j][k][l - 1]), max(f[i][j - 1][k - 1][l],f[i][j - 1][k][l - 1])) + Square[i][j] + Square[k][l];>
Time complexity
输入时最多有92个数,处理时要处理94次,所以总的时间复杂度为94+92次
综上所述,代码如下:
#include<iostream>
#include<utility>
using namespace std;
typedef long long ll;
#define fi(a,b) for(int i = a; i <= b; ++i)
#define fr(a,b) for(int i = a; i >= b; --i)
using pii = pair<int,int>;
int Square[10][10];
int f[10][10][10][10];//数组表示的状态数
int main()
{
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin >> n;
int a,b,c;
while(cin >> a >> b >> c && a && b && c)
Square[a][b] = c;
for(int i = 1; i <= n; ++i)
for(int j = 1; j <= n ; ++j)
for(int k = 1; k <= n; ++k)
for(int l = 1; l <= n; ++l)
{
f[i][j][k][l] = max(max(f[i - 1][j][k - 1][l],f[i - 1][j][k][l - 1]), max(f[i][j - 1][k - 1][l],f[i][j - 1][k][l - 1])) + Square[i][j] + Square[k][l];
if(i == k && j ==l) f[i][j][k][l] -= Square[i][j];//避免重复拿数
}
cout << f[n][n][n][n] << endl;
return 0;
}
感谢大家的阅读,如果觉得还不错就点个赞吧ヾ(≧▽≦*)o
洛谷P1004的更多相关文章
- 洛谷 P1004 方格取数 【多进程dp】
题目链接:https://www.luogu.org/problemnew/show/P1004 题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 ...
- 洛谷 - P1004 - 方格取数 - 简单dp
https://www.luogu.org/problemnew/show/P1004 这道题分类到简单dp但是感觉一点都不简单……这种做两次的dp真的不是很懂怎么写.假如是贪心做两次,感觉又不能证明 ...
- 棋盘DP三连——洛谷 P1004 方格取数 &&洛谷 P1006 传纸条 &&Codevs 2853 方格游戏
P1004 方格取数 题目描述 设有N $\times N$N×N的方格图(N $\le 9$)(N≤9),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字00.如下图所示(见样例): A ...
- 洛谷 P1004 方格取数 题解
P1004 方格取数 题目描述 设有 \(N \times N\) 的方格图 \((N \le 9)\),我们将其中的某些方格中填入正整数,而其他的方格中则放入数字\(0\).如下图所示(见样例): ...
- 洛谷 P1004 方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 方格取数洛谷p1004
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 【动态规划】洛谷P1004方格取数
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
- 洛谷P1004 方格取数-四维DP
题目描述 设有 N \times NN×N 的方格图 (N \le 9)(N≤9) ,我们将其中的某些方格中填入正整数,而其他的方格中则放入数字 00 .如下图所示(见样例): A 0 0 0 0 0 ...
- 四维动规 洛谷P1004方格取数
分析:这个题因为数据量非常小,可以直接用四维的DP数组 dp[i][j][k][l]表示第一个人走到位置(i,j),第二个人走到位置[k][l]时所取的数的最大和 状态转移方程可以轻松得出为:dp[i ...
- AC日记——方格取数 洛谷 P1004
题目描述 设有N*N的方格图(N<=9),我们将其中的某些方格中填入正整数,而其他的方格中则放 人数字0.如下图所示(见样例): A 0 0 0 0 0 0 0 0 0 0 13 0 0 6 0 ...
随机推荐
- 记录freeswitch的一个2833问题
概述 freeswitch是一款简单好用的VOIP开源软交换平台. 运营商内部新老系统混用,互联互通的问题较多,其中以DTMF码的问题最多,花样也多. 环境 CentOS 7.9 freeswitch ...
- 配置Ingress支持HTTPS访问(二):使用cert-manager申请证书
目录 一.系统环境 二.前言 三.Let's Encrypt和cert-manager简介 四.部署cert-manager 4.1 安装cert-manager 4.2 创建clusterissue ...
- C# Log4net 组件无法写日志 IsDebuged、IsInfoEnabled、IsErrorEnabled 全部为false
[assembly: log4net.Config.XmlConfigurator(ConfigFile = "Log4Net.config", Watch = true)] 如果 ...
- c#事件的实际应用场景
最简单的定义事件的语法 public event Action<bool> Refreash; 先介绍这个Action 这个Action是委托的快速实现方式,我用.net framewor ...
- Redis CPU过高排查
Redis CPU过高 测试环境经常卡住,经过排查是鉴权的不稳定,鉴权又经过redis查询.来到redis机器,发现cpu100%.redis的锅 top redis竟然cpu使用率达到100% 保存 ...
- Asp-Net-Core学习笔记:身份认证入门 _
前言 过年前我又来更新了~ 我就说了最近不是在偷懒吧,其实这段时间还是有积累一些东西的,不过还没去整理-- 所以只能发以前没写完的一些笔记出来 就当做是温习一下啦 PS:之前说的红包封面我还没搞,得抓 ...
- promise async 和 await
// promise 是专门用于解决回调地狱的 // 专门用于执行异步程序时使用promise语法 // 语法形式: // ...
- Python + redis操作Redis数据库
Redis redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(sorte ...
- 如何生成war包
pom.xml <packaging>war</packaging> 引入tomcat <dependency> <groupId>org.spring ...
- 使用vscode写Markdown并且导出为pdf(干货)
目录 序言 下载vscode 安装插件 markdown语法 导出为pdf 序言 大家在学习过程中都会有记笔记的好习惯(美观的笔记当然是上上选),于是,Markdown就是一个不错的选择,待会也会附上 ...