SYCOJ570传纸条
2021/7/13 6:06:32
本文主要是介绍SYCOJ570传纸条,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
题目—传纸条 (shiyancang.cn)
算法
(线性DP) O(n3)O(n3)
首先考虑路径有交集该如何处理。
可以发现交集中的格子一定在每条路径的相同步数处。因此可以让两个人同时从起点出发,每次同时走一步,这样路径中相交的格子一定在同一步内。
状态表示:f[k, i, j] 表示两个人同时走了k步,第一个人在 (i, k - i) 处,第二个人在 (j, k - j)处的所有走法的最大分值。
状态计算:按照最后一步两个人的走法分成四种情况:
两个人同时向右走,最大分值是 f[k - 1, i, j] + score(k, i, j);
第一个人向右走,第二个人向下走,最大分值是 f[k - 1, i, j - 1] + score(k, i, j);
第一个人向下走,第二个人向右走,最大分值是 f[k - 1, i - 1, j] + score(k, i, j);
两个人同时向下走,最大分值是 f[k - 1, i - 1, j - 1] + score(k, i, j);
注意两个人不能走到相同格子,即i和j不能相等。
时间复杂度
一共有 O(n3)O(n3) 个状态,每个状态需要 O(1)O(1) 的计算量,因此总时间复杂度是 O(n3)O(n3)。
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> using namespace std; const int N = 55; int n, m; int g[N][N]; int f[N * 2][N][N]; int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i ++ ) for (int j = 1; j <= m; j ++ ) scanf("%d", &g[i][j]); for (int k = 2; k <= n + m; k ++ ) for (int i = max(1, k - m); i <= n && i < k; i ++ ) for (int j = max(1, k - m); j <= n && j < k; j ++ ) for (int a = 0; a <= 1; a ++ ) for (int b = 0; b <= 1; b ++ ) { int t = g[i][k - i]; if (i != j || k == 2 || k == n + m) { t += g[j][k - j]; f[k][i][j] = max(f[k][i][j], f[k - 1][i - a][j - b] + t); } } printf("%d\n", f[n + m][n][n]); return 0; }
这篇关于SYCOJ570传纸条的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-12-23DevExpress 怎么实现右键菜单(Context Menu)显示中文?-icode9专业技术文章分享
- 2024-12-22怎么通过控制台去看我的页面渲染的内容在哪个文件中呢-icode9专业技术文章分享
- 2024-12-22el-tabs 组件只被引用了一次,但有时会渲染两次是什么原因?-icode9专业技术文章分享
- 2024-12-22wordpress有哪些好的安全插件?-icode9专业技术文章分享
- 2024-12-22wordpress如何查看系统有哪些cron任务?-icode9专业技术文章分享
- 2024-12-21Svg Sprite Icon教程:轻松入门与应用指南
- 2024-12-20Excel数据导出实战:新手必学的简单教程
- 2024-12-20RBAC的权限实战:新手入门教程
- 2024-12-20Svg Sprite Icon实战:从入门到上手的全面指南
- 2024-12-20LCD1602显示模块详解