方格取数
来源:互联网 发布:宋仲基宋慧乔婚礼知乎 编辑:程序博客网 时间:2024/05/01 12:12
题目链接
- 题意:
有N * N个格子,每个格子里有正数或者0,从最左上角往最右下角走,只能向下和向右,一共走两次(即从左上角走到右下角走两趟),把所有经过的格子的数加起来,求最大值SUM,且两次如果经过同一个格子,则最后总和SUM中该格子的计数只加一次。求SUM的最大值
(1 <= N <= 100),(0 <= value <= 1000) - 分析:
首先明白,两条线路除了起点和终点,一定不会相交,因为如果一旦相交,总可以找到一种方案使得不想交且结果不会更差。那么,就可以DP解决:dp[step][x][xx],表示现在两个人已经走了step步,第一个人在x行,第二个在xx行。这里有一个很重要的前提:如果需要保证两个路径不重复,那么在step相同的时候,两个人只要不在同一个点上,那么就可以保证两个线路没有交点。
const int MAXN = 110;int dp[2][MAXN][MAXN], ipt[MAXN][MAXN];int n;inline bool check(int x){ return x >= 0 && x < n;}inline void Max(int step, int now, int x, int xx, int tx, int txx){ int ty = step + 1 - tx, tyy = step + 1 - txx; if (!check(tx) || !check(ty) || !check(txx) || !check(tyy)) return; if (step != n + n - 3 && tx == txx && ty == tyy) return; int val = dp[now][x][xx] + ipt[tx][ty] + ipt[txx][tyy]; if (dp[now ^ 1][tx][txx] < val) dp[now ^ 1][tx][txx] = val;}int main(){ while (~RI(n)) { REP(i, n) REP(j, n) RI(ipt[i][j]); if (n == 1) { WI(ipt[0][0]); continue; } int step = n + n - 2, now = 0; CLR(dp, -1); dp[now][0][0] = ipt[0][0]; REP(s, step) { REP(i, n) REP(j, n) { int x = i, y = s - i, xx = j, yy = s - j; if (!check(x) || !check(y) || !check(xx) | !check(yy) || !~dp[now][x][xx]) continue; Max(s, now, i, j, i, j); Max(s, now, i, j, i + 1, j); Max(s, now, i, j, i, j + 1); Max(s, now, i, j, i + 1, j + 1); } CLR(dp[now], -1); now ^= 1; } cout << dp[now][n - 1][n - 1] - ipt[n - 1][n - 1] << endl; } return 0;}
1 0
- 方格取数(1)
- 方格取数(2)
- 关于方格取数
- 方格取数
- 方格取数
- 方格取数(1)
- 方格取数(2)
- 方格取数
- 方格取数
- 方格取数
- 方格取数
- 方格取数
- 方格取数
- 方格取数 蓝桥杯
- Noip2000方格取数
- 三次方格取数
- 方格取数
- NOIP2000方格取数
- HDU 1593 find a way to escape
- 在Mac上安装Ruby on Rails
- poj-2750
- LA 3211 Now or Later(2-SAT问题)
- ID3算法 改进的C4.5算法 决策树算法
- 方格取数
- iOS7—图像资源Images Assets
- Html中的过滤器的相关操作
- 全景探秘游戏设计艺术 笔记
- C++ Primer 【第四版】第三章 标准库类型
- 矩阵LU分解分块算法实现
- 无锁队列
- java泛型
- Android usb 无访问权限