前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >地宫取宝 (第五届蓝桥杯省赛C++A/B组)

地宫取宝 (第五届蓝桥杯省赛C++A/B组)

作者头像
dejavu1zz
发布2020-10-23 15:17:54
3310
发布2020-10-23 15:17:54
举报
文章被收录于专栏:奇妙的算法世界

题意描述

X 国王有一个地宫宝库,是 n×m 个格子的矩阵,每个格子放一件宝贝,每个宝贝贴着价值标签。 地宫的入口在左上角,出口在右下角。 小明被带到地宫的入口,国王要求他只能向右或向下行走。 走过某个格子时,如果那个格子中的宝贝价值比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。 当小明走到出口时,如果他手中的宝贝恰好是 k 件,则这些宝贝就可以送给小明。 请你帮小明算一算,在给定的局面下,他有多少种不同的行动方案能获得这 k 件宝贝。

输入格式 第一行 3 个整数,n,m,k,含义见题目描述。 接下来 n 行,每行有 m 个整数 Ci 用来描述宝库矩阵每个格子的宝贝价值。

输出格式 输出一个整数,表示正好取 k 个宝贝的行动方案数。 该数字可能很大,输出它对 1000000007 取模的结果。

数据范围 1≤n,m≤50, 1≤k≤12, 0≤Ci≤12

输入样例1: 2 2 2 1 2 2 1 输出样例1: 2 输入样例2: 2 3 2 1 2 3 2 1 5 输出样例2: 14

思路

这是一道动态规划的题目。我们可以用yxc的集合方法来分析动态规划。可以用dp[i][j][k][l]来表示,从起点到(i,j)点时,取得物品的数量为k,且最后一件取得的物品价值为l的方案数量,通过分析,我们可以发现,走到最后一步的方案数等于最后一步是从上走下来的方案数和最后一步是从左走过来的方案数相加,而最后一步又有取和不取两种情况,如果不取最后一件的话,那么状态方程很容易表示出来;如果取最后一件,则会比较复杂。根据题意,我们每次所取的最后一件一定是最大的,所以我们一定会有一个限定条件,即W==g[i][j],如果满足这个条件,那么就再进行一次循环,将方案数相加即可。关于细节问题,由于我们要选的是方案数,所以与物品价值大小无关。如果选第一件物品,则有初值dp[1][1][1][g[1][1]]=1。如果不选,则有dp[1][1][0][0]=1。

AC代码

代码语言:javascript
复制
#include<iostream>
using namespace std;
const int N=55;
const int MOD=1e9+7;
int dp[N][N][13][14];
int g[N][N];
int n,m,k;
int main(){
    cin>>n>>m>>k;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            cin>>g[i][j];
            g[i][j]++;
        }
    }
    dp[1][1][1][g[1][1]]=1;
    dp[1][1][0][0]=1;
    for(int i=1;i<=n;i++){
        for(int j=1;j<=m;j++){
            for(int u=0;u<=k;u++){
                for(int v=0;v<=13;v++){
                    dp[i][j][u][v]=(dp[i][j][u][v]+dp[i-1][j][u][v])%MOD;
                    dp[i][j][u][v]=(dp[i][j][u][v]+dp[i][j-1][u][v])%MOD;
                    if(u>0&&v==g[i][j]){
                        for(int c=0;c<v;c++){
                            dp[i][j][u][v]=(dp[i][j][u][v]+dp[i-1][j][u-1][c])%MOD;
                            dp[i][j][u][v]=(dp[i][j][u][v]+dp[i][j-1][u-1][c])%MOD;
                        }
                    }
                }
            }
        }
    }
    int res=0;
    for(int i=0;i<=13;i++) res=(res+dp[n][m][k][i])%MOD;
    cout<<res<<endl;
    return 0;
}
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/03/10 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 题意描述
  • 思路
  • AC代码
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档