来源:http://acm.hdu.edu.cn/showproblem.php?pid=1978
题目:
How many ways
Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 1150 Accepted Submission(s): 723
1.机器人一开始在棋盘的起始点并有起始点所标有的能量。
2.机器人只能向右或者向下走,并且每走一步消耗一单位能量。
3.机器人不能在原地停留。
4.当机器人选择了一条可行路径后,当他走到这条路径的终点时,他将只有终点所标记的能量。
我们的问题是机器人有多少种方式从起点走到终点。这可能是一个很大的数,输出的结果对10000取模。
对于每一组数据第一行输入两个整数n,m(1 <= n,m <= 100)。表示棋盘的大小。接下来输入n行,每行m个整数e(0 <= e < 20)。
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=110;
int n,m,ans;
int p[N][N];
int dp[N][N];
//bool vis[N][N];
/*void DFS1(int x,int y)
{
if(x==n-1&&y==m-1)
{
ans++;
return;
}
else
{
for(int i=x;i<=min(x+p[x][y],n-1);i++)
for(int j=y;j<=min(m-1,x+y+p[x][y]-i);j++)
if(!vis[i][j]&&(i!=x||j!=y))
{
vis[i][j]=true;
f1(i,j);
vis[i][j]=false;
}
}
}//深搜,会超时*/
int DFS2(int x,int y)
{
if(dp[x][y]!=0)
return dp[x][y]%10000;
else
{
for(int i=x;i<=min(x+p[x][y],n-1);i++)
for(int j=y;j<=min(m-1,x+y+p[x][y]-i);j++)
if(i!=x||j!=y)
dp[x][y]+=f2(i,j)%10000;
return dp[x][y]%10000;
}
}//记忆化搜索
int main()
{
int t;
scanf("%d",&t);
while(t--)
{
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++)
for(int j=0;j<m;j++)
scanf("%d",&p[i][j]);
memset(dp,0,sizeof(dp));
//memset(vis,false,sizeof(vis));
//ans=0;
//DFS1(0,0);
dp[n-1][m-1]=1;
printf("%d\n",DFS2(0,0)%10000);
//printf("%d\n",ans);
}
return 0;
}