x 國王有乙個地宮寶庫。是 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 22 1
輸出:2
再例如輸入:2 3 2
1 2 3
2 1 5
輸出:14
解法一:暴力dfs
#include #include#include
#include
#include
#include
using
namespace
std;
const
int inf=0x7fffffff
;const
long
long mod=1e9+7
;const
double pi=acos(-1
);bool vis[105
];int a[105][105
];int
n,m,k;
long
long
ans;
void dfs(int x,int y,int p,int
mx)
if(x==n-1&&y==m-1)
if(p==k-1&&a[x][y]>mx)
return
; }
if(a[x][y]>mx)
dfs(x+1,y,p,mx); //
不管格仔的價值是不是很大 都可以不拿該物品
dfs(x,y+1
,p,mx);
}int
main()
}dfs(
0,0,0,-1); //
格仔的**可能為 0 所以最初傳入最大值-1 才可以更新
cout
}
解法二:記憶化遞迴
可以這麼理解:先用暴力遞迴做出來,然後把它轉換為記憶化搜尋,即在頭查表,在尾寫表,表的引數和dfs的引數一致。
然後,就是用乙個陣列來記錄計算過的值
接著,你再在遞迴函式頭部——if (這個陣列的值不為初始值) return 這個值;最後,後面的遞迴返回值裡——「陣列=」遞迴返回值。
#include#include#include
using
namespace
std;
intn,m,k;
intans;
int mod=1e9+7
;int a[105][105
];int cache[50][50][20][20
]; bool vis[105
];
long
long dfs(int x,int y,int cot,int
mx)
long
long ans=0
;
if(x>=n||y>=m||cot>k)
if(x==n-1&&y==m-1)
if(cot==k-1&&a[x][y]>mx)
return
ans;
}if(a[x][y]>mx)
ans+=dfs(x+1
,y,cot,mx);
ans+=dfs(x,y+1
,cot,mx);
cache[x][y][cot][mx+1]=ans%mod; //
寫快取
return ans%mod; //
新增返回值
}int
main()
}memset(cache,-1,sizeof
(cache));
cout
<0,0,0,-1
);
return0;
}
記憶化搜尋 地宮取寶
問題描述 x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小...
地宮取寶(記憶化搜尋)
x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小明走到出口...
地宮取寶 C DFS 記憶化
x 國王有乙個地宮寶庫。是 n x m 個格仔的矩陣。每個格仔放一件寶貝。每個寶貝貼著價值標籤。地宮的入口在左上角,出口在右下角。小明被帶到地宮的入口,國王要求他只能向右或向下行走。走過某個格仔時,如果那個格仔中的寶貝價值比小明手中任意寶貝價值都大,小明就可以拿起它 當然,也可以不拿 當小明走到出口...