题目描述
设有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 提高组第四题
C++:
#include<stdio.h>
#include<iostream>
using namespace std;
int a[10][10]= {0},n,sum=0;
int f[10][10]= {0},hh[10][10]= {0};
void search(int m,int x,int y,int h,int s) {
int ji;
if(f[x][y]==h&&hh[x][y]==s) {
return;
}
if(x>n||y>n) {
return;
}
f[x][y]=h;
hh[x][y]=s;
if(x==n&&y==n&&h==1) {
ji=a[x][y];
a[x][y]=0;
search(1,1,1,2,s+ji);
a[x][y]=ji;
} else if(x==n&&y==n&&h==2) {
if(s>sum) {
sum=s;
}
return;
} else {
if(a[x][y]!=0) {
ji=a[x][y];
a[x][y]=0;
search(m+1,x+1,y,h,s+ji);
search(m+1,x,y+1,h,s+ji);
a[x][y]=ji;
}
search(m+1,x+1,y,h,s);
search(m+1,x,y+1,h,s);
}
}
int main() {
int i,j,k;
cin>>n;
while(1) {
cin>>i>>j>>k;
if(i==0&&j==0&&k==0) {
break;
}
a[i][j]=k;
}
search(1,1,1,1,0);
cout<<sum;
return 0;
}
Pascal:
var
a:array[0..20,0..20] of longint;
dp:array[0..100,0..20,0..20] of longint;
n,x,y,z,k,i,j:longint;
function max(a,b:longint):longint;
begin
if a>b then exit(a) else exit(b);
end;
begin
fillchar(a,sizeof(a),0);
read(n);
while 1=1 do
begin
read(x,y,z);
if (x=0) and (y=0) and (z=0) then break;
a[x,y]:=z;
end;
fillchar(dp,sizeof(dp),0);
for k:=1 to 2*n do
for i:=1 to k do
for j:=1 to k do
begin
dp[k,i,j]:=max(max(dp[k-1,i,j],dp[k-1,i-1,j-1]),max(dp[k-1,i-1,j],dp[k-1,i,j-1]));
if i<>j then dp[k,i,j]:=dp[k,i,j]+a[k-i+1,i]+a[k-j+1,j]
else dp[k,i,j]:=dp[k,i,j]+a[k-j+1,j];
end;
write(dp[2*n,n,n])
end.
/*k是一共走几步 i是第一次向右走几步 j是第二次向右走几步*/