深度優先搜索——地宮取寶
阿新 • • 發佈:2017-10-07
sed 地圖 估計 分享 eof 格式 標簽 計算 clas
描述:
有一個地宮寶庫是 n x m 個格子的矩陣。每個格子放一件寶貝。每個寶貝貼著價值標簽。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格子時,如果那個格子中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它(當然,也可以不拿)。當小明走到出口時,如果他手中的寶貝恰好是k件,則這些寶貝就可以送給小明。 請你幫小明算一算,在給定的局面下,他有多少種不同的行動方案能獲得這k件寶貝。 【數據格式】 輸入一行3個整數,用空格分開:n m k (1<=n,m<=50, 1<=k<=12)。 接下來有 n 行數據,每行有 m 個整數 Ci (0<=Ci<=12)代表這個格子上的寶物的價值。 要求輸出一個整數,表示正好取k個寶貝的行動方案數。該數字可能很大,輸出它對 1000000007 取模的結果。 例如,輸入: 2 2 2 1 2 2 1 程序應該輸出: 2 再例如,輸入: 2 3 2 1 2 3 2 1 5 程序應該輸出: 14#include <iostream> #include <cmath> #include <cstring> using namespace std; const int N=1000000007; int ans,n,m,k;//n行m列 k個寶貝 int d[51][51][13][14];//保存狀態 int p[51][51];//地圖中每個地點寶貝的價值 int dfs(int x,int y,int num,int maxvalue){ if(d[x][y][num][maxvalue+1]!=-1){//如果狀態庫裏有記錄就直接在庫裏查找,不用遞歸計算實現代碼return d[x][y][num][maxvalue+1]; //我不明白為什麽要坐標+1 //傳進去的值是-1啊,為了防止越界當然要加一 } int t=0;//這個估計是行動方案數的記錄 if(x==n-1&&y==m-1){//到達終點 if(p[x][y]>maxvalue){//價值比現有的高 if(num==k||num==k-1) t++; //剛好或差一件都可以+1 } else if(num==k){//剛好就可以+1 t++; }//cout << "終點" <<x << "," << y << " "<< num << " "<< maxvalue<< " " << t <<endl; d[x][y][num][maxvalue+1]=t; return d[x][y][num][maxvalue+1];//這個返回暫時沒看懂 } if(x+1<n){//如果再走一步不越界 if(p[x][y]>maxvalue){//價值大於現在 執行下面兩種情況 t+=dfs(x+1,y,num+1,p[x][y]); t%=N; t+=dfs(x+1,y,num,maxvalue); t%=N; } else{//小於就只有一種情況 繼續走 t+=dfs(x+1,y,num,maxvalue); t%=N; } } if(y+1<m){//如果再走一步不越界 if(p[x][y]>maxvalue){//價值大於現在 執行下面兩種情況 t+=dfs(x,y+1,num+1,p[x][y]); t%=N; t+=dfs(x,y+1,num,maxvalue); t%=N; } else{//小於就只有一種情況 繼續走 t+=dfs(x,y+1,num,maxvalue); t%=N; } } //cout << "中途" <<x << "," << y << " "<< num << " "<< maxvalue<< " " << t <<endl; d[x][y][num][maxvalue+1]=t; return d[x][y][num][maxvalue+1];//max坐標+1 } int main(){ cin >> n >> m >> k; for(int i=0;i<n;i++) for(int j=0;j<m;j++) cin >> p[i][j]; // for(int i=0;i<51;++i) // for(int j=0;j<51;++j) // for(int p=0;p<13;++p) // for(int q=0;q<14;++q) // d[i][j][p][q]=-1; memset(d,-1,sizeof(d));//全部賦值-1 cout << dfs(0,0,0,-1); //從坐標(0,0) 寶物數0 最大值為-1開始 return 0; }
深度優先搜索——地宮取寶