CodeVs 1043 方格取数
2015-11-26 19:57
246 查看
$n \times n$ 的方格,每个格子有个自然数。一人在方格中,只能向右或下走。从左上角到右下角走两次,问最大可以取得多大的数字(每个数字取了就没了,也就是说两次经过同一个位置只能得到一个值)。
考虑两次一起走,每一行经过的段是两个线段假设是 [a, b] 和 [c, d]。当前一行状态是 [a, b] [c, d] 时转移是来自上一行的 b 等于这一行的 a, 并且上一行的 d 等于这一行的 c。
这样的话复杂度是 $O(n^9)$,大概是不能过的,但是考虑一下剪枝,可以让 $c \ge a$,因为不然就可以把两次路径后半部分交换看做是 $c \ge a$ 的。
比如 3-5 和 1-9,可以改成 1-5 和 3-9。
这样在 n = 10 的时候大概是 $3\times 10^7$。
考虑两次一起走,每一行经过的段是两个线段假设是 [a, b] 和 [c, d]。当前一行状态是 [a, b] [c, d] 时转移是来自上一行的 b 等于这一行的 a, 并且上一行的 d 等于这一行的 c。
这样的话复杂度是 $O(n^9)$,大概是不能过的,但是考虑一下剪枝,可以让 $c \ge a$,因为不然就可以把两次路径后半部分交换看做是 $c \ge a$ 的。
比如 3-5 和 1-9,可以改成 1-5 和 3-9。
这样在 n = 10 的时候大概是 $3\times 10^7$。
#include <bits/stdc++.h> using std::vector; const int MAXN = 12; const int MAXS = 1 << MAXN; int dp[MAXN][MAXS]; int a[MAXN][MAXN]; int sum[MAXN][MAXN]; struct Status { int a, b, c, d; int sumValue(int i) { int res = sum[i][b + 1] - sum[i][a] + sum[i][d + 1] - sum[i][c]; if (c <= b) res -= sum[i][b + 1] - sum[i][c]; return res; } }; vector<Status> status; #define rep(i, l, r) for (int i = l; i < r; i++) int statusTable(int n) { int res = 0; rep(i0, 0, n) rep(i1, i0, n) rep(j0, i0, n) rep(j1, j0, n) { status.push_back((Status) {i0, i1, j0, j1}); res++; } return res; } int main() { int n; scanf("%d", &n); int sCnt = statusTable(n); int x, y, v; for (; scanf("%d %d %d", &x, &y, &v), (x + y + v); ) a[x][y] = v; for (int i = 1; i <= n; i++) { for (int j = 1; j <= n; j++) sum[i][j] = sum[i][j - 1] + a[i][j]; } rep(i, 0, sCnt) if (status[i].a == 0 && status[i].b >= status[i].c - 1) { dp[1][i] = status[i].sumValue(1); } for (int i = 2; i <= n; i++) { rep(j, 0, sCnt) rep(k, 0, sCnt) { if (status[j].b - status[k].a || status[j].d - status[k].c) continue; dp[i][k] = std::max(dp[i][k], dp[i - 1][j] + status[k].sumValue(i)); } } int result = 0; rep(i, 0, sCnt) if (status[i].d == n - 1 && status[i].b == n - 1) { result = std::max(dp [i], result); } printf("%d\n", result); return 0; }
相关文章推荐
- jquery.tablesorter.js 学习笔记
- matlab 使用SVM 对鸢尾鼠植物2分类
- URAL 1002 Phone Numbers
- 【SGU 128】snake 线段树
- PS: Understanding deep features with computer-generated imagery___ICCV2015
- 有趣的单精度浮点数(float)
- 【C语言】两个有序单链表的合并
- 互联网产品 要不要做用户调研
- 学习排序 Learning to Rank 小结
- 工具栏CollectionsJAVA128
- Android高效获取指定类型文件,获取文件不求人!
- Redis常用命令
- Visual Studio的函数unsafe报错问题
- 整数划分问题
- 将文件或目录拷贝到另一个Linux系统的命令scp
- HDOJ--1262--寻找素数对
- AT&T汇编基础]
- 3D引擎:Horde3D:读取Shader文件流程(二)
- 互联网产品 要不要做用户调研
- Android MVP架构和MVC架构比较(有代码示例)