传送门:http://acm.bjtu.edu.cn/problem/detail?pid=1703
背景:本题在大一新生赛前曾看过一次,当时觉得好神奇,没想到这种需要思维的过程也能用算法实现,(当时自己还是too young too simple啊,现在Alphago都能战胜人类了。。。)经过假期的学习,还有开学后的讲座,掌握了DFS,BFS,记忆化搜索,终于发现这道题目也不是那么高不可攀了,花了半个小时敲了出来结果过不了样例,T T ,开始无休止调试,一度以为自己的思路完全错误,后来才发现有一个变量开成了全局变量,结果在栈的反复调用的情况下,数值被不断修改。。。第二天改成后直接AC。
解题思路:记忆化搜索(dp也许也行?),每次记录下从该点到终点体力消耗的最小值。而从每个点出发只有两个选择,向下或者向右,所以只去最小值就可以了。
代码如下:
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
int n;
int map[105][105];
int strength[105][105];
int dx[2]={0,1};
int dy[2]={1,0};
int DFS(int x,int y)
{
int road[2];
if(strength[x][y]!=0)
return strength[x][y];
int i;
for(i=0;i<=1;i++)
{
road[i] = 10000;
int xx = x+dx[i];
int yy = y+dy[i];
if(xx==n-1 && yy==n-1)
{
road[i] = map[xx][yy];
continue;
}
else if(xx < n && yy< n )
{
road[i] = DFS(xx,yy);
}
}
return strength[x][y] = min(road[0],road[1])+map[x][y];
}
int main()
{
//freopen("text.txt","r",stdin);
int t,i,j;
scanf("%d",&t);
while(t--)
{
memset(strength,0,sizeof(strength));
scanf("%d",&n);
for(i=0;i<n;i++)
{
for(j=0;j<n;j++)
scanf("%d",&map[i][j]);
}
DFS(0,0);
cout << strength[0][0] << endl;
}
//cout << "Hello world!" << endl;
return 0;
}