地宫取宝——动态规划

news/2025/3/15 15:00:35/文章来源:https://www.cnblogs.com/foxt/p/18773684

地宫取宝

题目描述

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 3 2
1 2 3
2 1 5

样例输出

14

解题思路

采用动态规划的方法,首先确定dp数组含义。因为不仅要考量行列信息,还有考量当前手中的宝物数量,同时宝物拿取存在要求,必须当前格子宝物价值比手中所有宝物价值都大才可以取,所以采用四维数组。

dp[i][j][k][w]表示在当前第i行第j列时手中宝物数量为k,手中宝物的价值不超过w2情况下的种类数。

边界状态

  1. 第一行第一列手中宝物数量为0时,种类数为1.
  2. 第一行第一列手中宝物数量为1时,且手中宝物价值大于第一行第一列的价值种类数为1.

状态转移方程

  1. 不拿,dp[i][j][k][w]=dp[i-1][j][k1][w]+dp[i][j-1][k1][w]
  2. 拿,dp[i][j][k][w]=dp[i-1][j][k1-1][wealth[i][j]]+dp[i][j-1][k1-1][wealth[i][j]],拿当前的第i行第j列的宝物的种类数来自(1)上一行k-1件商品且最大宝物价值不超过当前格子宝物价值的种类数。(2)前一列k-1件商品且最大宝物价值不超过当前格子宝物价值的种类数。
  3. 当前dp[i][j][k][w]种类为拿当前的宝物种类数和不拿当前宝物的种类数之和。

注意:种类数较大,需要时刻注意取模问题。

代码

import java.util.Scanner;public class Main {static final int MOD = 1000000007;public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt();int m = scanner.nextInt();int k = scanner.nextInt();//dp[i][j][k][m]---棋盘第i行,第j列上有k件宝物并且宝物最大价值不超过m的种类数//创建棋盘宝物价值数组int[][] wealth=new int[n+1][m+1];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){wealth[i][j]=scanner.nextInt();}}//创建四维数组并初始化int[][][][] dp=new int[n+1][m+1][k+1][13];for(int i=1;i<=n;i++){for(int j=1;j<=m;j++){for(int k1=0;k1<=k;k1++){for(int w2=0;w2<13;w2++){//边界状态赋值if (i == 1 && j == 1) {//边界状态k1=0 手上没有宝物,不取宝物,则第1行第1列手上宝物为0,最大价值不超过w2的种类数为1//k1=1,w2>wealth[1][1]  在第1行第1列拿取一个宝物,要拿宝物,那么最大价值要超过当前格子的宝物价值,其种类数为1if (k1 == 0 || (k1 == 1 && w2 > wealth[1][1])) {dp[i][j][k1][w2] = 1;}continue;}int num_notake=0;int num_take=0;//拿当前的商品if(k1>0&&w2>wealth[i][j]){num_take=dp[i-1][j][k1-1][wealth[i][j]]%MOD+dp[i][j-1][k1-1][wealth[i][j]] % MOD;num_take%=MOD;}//不取当前商品num_notake=dp[i-1][j][k1][w2]%MOD+dp[i][j-1][k1][w2] % MOD;//这一步很重要,如果不取模,那么结果将会溢出,加数取模后和应该继续取模num_notake%=MOD;dp[i][j][k1][w2]=(num_notake+num_take)%MOD;}}}}System.out.println(dp[n][m][k][12]);}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/899211.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

20250315

1. 20号胶 3-5的细分

语音交友app源码,优化白屏降低用户负面情绪

语音交友app源码,优化白屏降低用户负面情绪目标: 缩小打包体积,优化白屏时间路由懒加载const Home = () => import(/* webpackChunkName: "home" */"@/views/home/index.vue"); const MetricGroup = () => import(/* webpackChunkName: "met…

Visio绘制时间轴安排图的方法

本文介绍基于Visio软件绘制时间轴、日程安排图、时间进度图等的方法~本文介绍基于Visio软件绘制时间轴、日程安排图、时间进度图等的方法。在很多学习、工作场合中,我们往往需要绘制如下所示的一些带有具体时间进度的日程安排、工作流程、项目进展等可视化图表。而基于Visio软…

华为---MUX VLAN简介及示例配置

https://blog.csdn.net/lehe99/article/details/1426209886.4 配置及解析 system-view [Huawei]sysname R [R]interface GigabitEthernet 0/0/0 [R-GigabitEthernet0/0/0]ip address 192.168.11.254 24 [R]interface LoopBack 11 [R-LoopBack11]ip address 11.11.11.11 32 syst…

SQL Server 列存储HTAP介绍

本篇文章是我线下活动分享的一个活动PPT,现在分享在我的个人博客中

基于QWidget打造的进度条控件(等待控件、加载控件)

效果图功能支持设置加载进度条颜色 支持设置中间显示文字、文字颜色、文字大小 基于QWidget开发, 开箱即用。全部代码 CircleWaitingWidget.h #pragma once #include <QWidget>/// /// 环状等待控件。 /// class CircleWaitingWidget : public QWidget {Q_OBJECTpubli…

完全开源的SQL2API低代码工具SQLREST

在现代 Web 应用中,API(应用程序编程接口)是连接前端与后端业务逻辑的重要桥梁。传统的 API 开发方式通常需要手动编写大量代码,尤其是当需要与数据库交互时,开发效率往往较低。 一、什么是 SQLREST SQLREST是一款完全开源的SQL2API低代码工具,帮助用户同步编写SQL或简单…

【晶体】范得华力,氢键

晶体的分类: 1、 金属晶体,比如铜,2、离子晶体,比如NaCl晶体,盐,3、分子晶体,比如:干冰 4、共价晶体,比如说SiO2 分子晶体,是由分子间范得华力吸引形成的。 什么是 范得华力? 分子的部分区域是正电,部分区域是负电。分子与分子之间,正负吸引的力,就是范得华…

JDK8-日历类--java进阶day07

JDK7和JDK8之间的时间API比较1.日历类1.LocalDateTime LocalDateTime最为齐全,只要掌握这个类,另外两个都是一样的now方法获取到此刻时间,of方法设置想要的时间如下图2.LocalDateTime与LocalDate和LocalTime之间的转换.3.get方法获取时间使用get,后面加上自己想要获取的时间…

ASE50N25-ASEMI光伏逆变器专用ASE50N25

ASE50N25-ASEMI光伏逆变器专用ASE50N25编辑:LL ASE50N25-ASEMI光伏逆变器专用ASE50N25 型号:ASE50N25 品牌:ASEMI 封装:TO-220F 最大漏源电流:50A 漏源击穿电压:250V 批号:最新 RDS(ON)Max:45mΩ 引脚数量:3 沟道类型:N沟道MOS管 封装尺寸:如图 特性:MOS管、N沟…

vcpkg 跨平台的c/c++库包管理工具,以libssh为例

‌vcpkg‌是一个由微软开发的开源C/C++库包管理器,支持Windows、Linux和macOS操作系统。 功能:可以自动识别依赖,并进行编译、安装。 例如,libssh库依赖openssl、zlib等。自己编译需要先下载依赖的源码、编译、安装,然后再编译libssh,很麻烦。vcpkg可以自动解决这些问题。…