14
思路:
自己尝试写的代码,虽然不全对,但还是要尝试自己写,真正比赛的时候才不会让你百度看别人的思路(当然也百度不到):
代码:
#include
#include
using namespace std;
int n,m,k,map[51][51],cnt=0;
void dfs(int x,int y,int num,int sum)
{
int i,j;
if (x==n&&y==m) //到达终点
{
if (num == k)//物品数与规定的相等,一种结果
{
cnt++;
}
if (num == k-1 && map[x][y] > sum) //最后地图价值 大于手中的,可以不拿,也是一种结果
{
cnt++;
}
return ;
}
if (x+1<=n) //可以向下走
{
if (map[x][y] > sum) //地图价值大于可以拿走
{
dfs(x+1,y,num+1,map[x][y]);
}
dfs(x+1,y,num,sum); //也可以不拿
}
if (y+1<=m) //可以向右走
{
if (map[x][y] > sum)
{
dfs(x,y+1,num+1,map[x][y]);
}
dfs(x,y+1,num,sum);
}
}
int main()
{
int i,j;
cin>>n>>m>>k;
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
cin>>map[i][j];
dfs(1,1,0,-1);//初始坐标,手中物品数,-1为手中的最大值
cout<
学习的正确的代码:用4维数组记录每种状态,减少搜索次数
代码:
#include
#include
#define N 1000000007
using namespace std;
typedef long long LL;
LL n,m,k;
LL map[50][50];
LL flag[50][50][50][50]; //记录当在下标n,m处,手中有多少个物品,最大值是几,
LL dfs(LL x,LL y,LL sum,LL v)
{
LL s=0,t;
if (flag[x][y][sum][v+1] != -1)//有值,直接返回结果,减少搜索次数
return flag[x][y][sum][v+1];
if (x == n && y == m)//到达终点
{
if (sum == k || (sum == k-1 && map[n][m] > v)) //物品数量和规定的k相等,或者最后一个地图价值大于手中的可以不拿
{
flag[x][y][sum][v+1] = 1;
return 1;
}
else
{
flag[x][y][sum][v+1] = -1;
return 0;
}
}
if (x+1<=n) //向下走合法
{
if (map[x][y] > v) //地图价值大于手中价值 ,可拿
{
s += dfs(x+1,y,sum+1,map[x][y])%N;
}
s += dfs(x+1,y,sum,v)%N;
}
if (y+1<=m) //向右走合法
{
if (map[x][y] > v)
{
s += dfs(x,y+1,sum+1,map[x][y])%N;
}
s += dfs(x,y+1,sum,v)%N;
}
flag[x][y][sum][v+1] = s%N;
return flag[x][y][sum][v+1];
}
int main()
{
int i,j;
memset(flag,-1,sizeof(flag));
cin>>n>>m>>k;
for (i=1; i<=n; i++)
for (j=1; j<=m; j++)
{
cin>>map[i][j];
}
cout<