1212. 地宮取寶
阿新 • • 發佈:2020-09-06
狀態表示:f(i, j, k, c) 表示走到(i, j)格子,已經取到k件寶物,並且最後一件寶物的價值為c的所有取法的集合,儲存數量屬性
狀態計算:集合劃分
\(f(i, j, k, c)=\) 集合中所有的數量加起來
通過集合分析得到狀態轉移方程:
\(
f(i, j, k, c) = f(i-1,j,k,c) + f(i,j-1,k,c) + \delta ,\\
其中 \delta = f(i,j-1,k-1,c') + f(i-1,j,k-1,c'),(k>0,c'=0,1,2,...,c-1)\\
f(1, 1,1,w[1][1]) = 1,f(1,1,0,0) = 1
\)
#include<iostream> using namespace std; const int N = 60, MOD = 1000000007; int n, m, k; int f[N][N][13][14]; int w[N][N]; int main(){ cin >> n >> m >> k; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++){ cin >> w[i][j]; w[i][j] ++; } f[1][1][1][w[1][1]] = 1; f[1][1][0][0] = 1; for(int i = 1; i <= n; i ++) for(int j = 1; j <= m; j ++){ if(i == 1 && j == 1) continue; for(int k = 0; k <= 12; k ++) // 此處可以只迴圈到輸入的k為止 for(int c = 0; c <= 13; c ++){ int &val = f[i][j][k][c]; val = (val + f[i][j - 1][k][c]) % MOD; val = (val + f[i - 1][j][k][c]) % MOD; if(k > 0 && w[i][j] == c) for(int _c = 0; _c < c; _c ++){ val = (val + f[i][j - 1][k - 1][_c]) % MOD; val = (val + f[i - 1][j][k - 1][_c]) % MOD; } } } int res = 0; for(int i = 1; i <= 13; i ++) res = (res + f[n][m][k][i]) % MOD; //統計符合條件的答案 cout << res; }