1212. 地宫取宝

状态表示: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;
}
posted @ 2020-09-06 14:36  yys_c  阅读(185)  评论(0编辑  收藏  举报