您的位置:首页 > 编程语言 > C语言/C++

蓝桥杯 2014 本科B组 c++ 预赛 第九题 地宫取宝

2015-04-08 21:29 288 查看
<pre name="code" class="cpp">//参考的word答案,剪枝处理的很好。判断出口的条件也很好,学习!
#include <cstdio>
#include <cmath>
#include <algorithm>
#include <cstring>
using namespace std;
int map[55][55];
int n, m, k, sum = 0;
int DFS(int x, int y, int big, int nowHave)
{
if(nowHave > k)
return 0;
if(x == n && y == m)
{
if(nowHave == k || nowHave == k - 1 && map
[m] > big)
sum++;
sum %= 1000000007;
}
if(x + 1 <= n)
{
if(map[x][y] > big)
DFS(x + 1, y, map[x][y], nowHave + 1);
DFS(x + 1, y, big, nowHave);
}
if(y + 1 <= m)
{
if(map[x][y] > big)
DFS(x, y + 1, map[x][y], nowHave + 1);
DFS(x, y + 1, big, nowHave);
}
}
int main()
{
scanf("%d%d%d", &n, &m, &k);
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
scanf("%d", &map[i][j]);
DFS(1, 1, 0, 0);
printf("%d", sum);
return 0;
}


//DFS的参数基本上都是这样的,第一个参数是当前要考虑的块,第二个参数是前面已经考虑的集合的某个特征数。无论全排列还是这种类似背包问题//结果比答案多了一倍,因为判断出口的条件重复 //思路似乎是对的啊。。和人家的答案比,也是DFS,也是三个参数 #include<cstdio>//好好想想循环的本质,既然可以用循环,只有2个方向,可以直接写,还好理解些! int count;int matrix[51][52];/*int X[2]={0,1};int Y[2]={1,0};//(0,1)是往下,(1,0)是往右
*/int w,h,k; void dfs(int maxbefore,int x,int y,int m){//应该只要存储最大的就好了.m为当前块不算,之前的块数 //关于乘以的问题,问题似乎出在这里 ,嗯!是的! if((x==h&&y==w-1||x==h-1&&y==w)&&m==k){//如果当前小明手里的个数够了.咦好像不需要x和y的标准吧 //要的,如果中间就达到k,后面还有很多路走的 count++; return; } /*if(maxbefore<matrix[x][y]){//只有当当前的块比最大值大时,才考虑拿不拿
//不拿 fun(maxbefore,) } */ if(x>=h||y>=w) return; //for(int i=0;i<2;i++){ /*int newX=x+X[i]; int newY=y+Y[i]; if(newX>=h||newY>=w) continue;*/ //dfs(maxbefore,newX,newY,m);//这个不选 dfs(maxbefore,x+1,y,m); //本块不拿。m之前的块数 dfs(maxbefore,x,y+1,m);//本块不拿 if(maxbefore<matrix[x][y]&&m<k){//注意这里的剪枝条件
//不拿dfs(matrix[x][y],x+1,y,m+1);//本块拿 dfs(matrix[x][y],x,y+1,m+1);//本块拿 }}int main(){scanf("%d%d%d",&h,&w,&k);getchar();for(int i=0;i<h;i++){for(int j=0;j<w;j++){scanf("%d",&matrix[i][j]);}/getchar();}dfs(0,0,0,0);printf("%d\n",count);return 0; }

                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐