题目
题目描述
设有 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
说明
NOIP 2000 提高组第四题
题解
比较 H2O 的动态规划题。
应该可以用 3 维状态,我懒得想,直接用了 4 维。
设 $f[x1][y1][x2][y2]$为两条路径分别走到了:$(x1,y1),(x2,y2)$这两个点时的答案。
设 $v[x][y]$为坐标 $(x,y)$上的数字。
$f[x1][y1][x2][y2]=max(f[x1-1][y1][x2-1][y2],f[x1-1][y1][x2][y2-1],f[x1][y1-1][x2-1][y2],f[x1][y1-1][x2][y2-1])+v[x1][y1]+v[x2][y2]$
如果 $x1=x2$且 $y1=y2$则不加 $v[x2][y2]$或不加 $v[x1][y1]$
代码:
#include <bits/stdc++.h>
using namespace std;
int n,mp[10][10],f[10][10][10][10];
int dfs(int ha,int wa,int hb,int wb)
{
if(ha<1|wa<1|hb<1|wb<1)return 0;
int & k=f[ha][wa][hb][wb];if(k>=0)return k;
k=max(dfs(ha-1,wa,hb-1,wb),dfs(ha-1,wa,hb,wb-1));
k=max(k,max(dfs(ha,wa-1,hb-1,wb),dfs(ha,wa-1,hb,wb-1)));
return k+=mp[ha][wa]+((ha!=hb|wa!=wb)?mp[hb][wb]:0);
}
int main()
{
memset(f,-1,sizeof(f)),scanf("%d",&n);
for(int a,b,c;scanf("%d%d%d",&a,&b,&c),a|b|c;mp[a][b]=c);
printf("%d\n",dfs(n,n,n,n));
return 0;
}
1 条评论
【题解】传纸条 动态规划 LUOGU – 1006 – K-XZY · 2017年5月9日 8:24 下午
[…] 解法见【题解】方格取数 […]