首页 > 其他分享 >AcWing 1212. 地宫取宝

AcWing 1212. 地宫取宝

时间:2024-03-13 14:58:44浏览次数:29  
标签:1212 int max num static 宝物 取宝 dp AcWing

Problem: AcWing 1212. 地宫取宝

文章目录

思路

这是一个动态规划问题,我们需要找到所有可能的路径,其中每个路径中的宝物价值都是递增的,并且恰好有k个宝物。我们可以使用一个四维的动态规划数组dp[i][j][p][q],其中i和j表示当前的位置,p表示当前手中宝物的数量,q表示当前手中宝物的最大价值。然后,我们可以使用深度优先搜索来遍历所有可能的路径。

解题方法

首先,我们初始化动态规划数组,然后遍历所有可能的位置、宝物数量和宝物最大价值。对于每个位置,如果宝物数量和宝物最大价值都为0,或者宝物数量为1且宝物最大价值等于当前位置的宝物价值,那么就有一种方案。然后,如果当前位置的行数大于1,那么可以从上面的位置走到当前位置,如果宝物最大价值大于等于当前位置的宝物价值,那么还可以选择当前位置的宝物。同样,如果当前位置的列数大于1,那么可以从左边的位置走到当前位置,如果宝物最大价值大于等于当前位置的宝物价值,那么还可以选择当前位置的宝物。最后,对于所有可能的宝物最大价值,将对应的方案数加到答案中。

复杂度

时间复杂度:

O ( n 2 ∗ k 2 ) O(n^2 * k^2) O(n2∗k2),其中n是地宫的大小,k是需要收集的宝物数量。因为我们需要遍历所有可能的位置、宝物数量和宝物最大价值。

空间复杂度:

O(n^2 * k^2),我们需要一个四维数组来存储动态规划的状态。

Code

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.StreamTokenizer;

public class Main {
	static BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
	static PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
	static StreamTokenizer sr = new StreamTokenizer(in);
	static int n, m, k;
	static int MAXN = 56, MAXK = 15;
	static int[][] arr = new int[MAXN][MAXN];
	static long MOD = 1000000007;
	static long[][][][] dp = new long[MAXN][MAXN][MAXK][MAXK];

	public static void main(String[] args) throws IOException {
		n = nextInt();
		m = nextInt();
		k = nextInt();
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < m; j++) {
				arr[i][j] = nextInt();
			}
		}
		init();

		out.println(dfs(0, 0, 0, -1));
		out.flush();

	}

	private static void init() {
		// TODO Auto-generated method stub
		for (int i = 0; i < MAXN; i++) {
			for (int j = 0; j < MAXN; j++) {
				for (int k = 0; k < MAXK; k++) {
					for (int l = 0; l < MAXK; l++) {
						dp[i][j][k][l] = -1;
					}
				}
			}
		}

	}

	/**
	 * 
	 * @param x
	 * @param y
	 * @param num 当前已经收集宝物的个数
	 * @param max 当前收集宝物的最大值
	 * @return 为什么要有这个最大值? 因为题目中强调 走过某个格子时,如果那个格子中的宝贝价值
	 *         比小明手中任意宝贝价值都大,小明就可以拿起它(当然,也可以不拿)。
	 * 
	 */

	private static long dfs(int x, int y, int num, int max) {
		// TODO Auto-generated method stub
		if (dp[x][y][num][max + 1] != -1) {
			return dp[x][y][num][max + 1];
		}

		// 结束条件 : 到达终点
		if (x == n - 1 && y == m - 1) {
			// 1. 收集宝藏的数量等于k 或者 收集宝藏的数量为k-1但是最后一个位置
			// (也就是当前位置)大于之前收集到的宝藏的最大值 就可以加上当前这个满足k个
			if (num == k || (num == k - 1 && max < arr[n - 1][m - 1])) {
				// dp[x][y][num][max + 1] = 1;
				return 1;
			} else {
				// dp[x][y][num][max + 1] = 0;
				return 0;
			}
		}
		long s = 0;
		// 向下
		if (x + 1 < n) {
			// 判断当前数字可拿不可拿
			// 满足题意 可以拿走
			if (max < arr[x][y]) {
				s += dfs(x + 1, y, num + 1, arr[x][y]);
			}
			s += dfs(x + 1, y, num, max);
			s %= MOD;
		}

		if (y + 1 < m) {
			if (max < arr[x][y]) {
				s += dfs(x, y + 1, num + 1, arr[x][y]);
			}
			s += dfs(x, y + 1, num, max);
			s %= MOD;
		}

		dp[x][y][num][max + 1] = s;
		return dp[x][y][num][max + 1];

	}

	static int nextInt() throws IOException {
		sr.nextToken();
		return (int) sr.nval;
	}

}

标签:1212,int,max,num,static,宝物,取宝,dp,AcWing
From: https://blog.csdn.net/m0_73939789/article/details/136635598

相关文章

  • 破链成环-acwing第131场周赛-奶牛报数
    5364.奶牛报数-AcWing题库有 n 头奶牛,围成一圈,顺时针依次编号为 1∼n。其中,第 i 头奶牛的重量为 ai。现在,我们需要选择一头奶牛,并从该奶牛开始,所有奶牛按照顺时针的顺序进行 1∼n报数。报数完毕后,所有报出的数在 [l,r)范围内的奶牛,会被选中制作牛肉。我们希......
  • P8612 [蓝桥杯 2014 省 AB] 地宫取宝
    https://www.luogu.com.cn/problem/P8612#submit原始暴搜代码,没有记忆化,会tle#include<iostream>#include<vector>#include<algorithm>#include<math.h>#include<sstream>#include<string>#include<string.h>#include<iomanip&g......
  • Acwing166 数独题解 - DFS剪枝优化
    166.数独-AcWing题库题意数独是一种传统益智游戏,你需要把一个9×9的数独补充完整,使得数独中每行、每列、每个3×3的九宫格内数字1∼9均恰好出现一次。请编写一个程序填写数独。思路搜索+剪枝(优化搜索顺序、位运算)优化搜索顺序:很明显,我们肯定是从当前能填合法......
  • 蓝桥杯-地宫取宝
    这是一个dp题,可以用4维数据来表示所有的状态。但是有一个需要注意的点,一般来说,对于每个坐标,有拿跟不拿两种情况,如果没有拿任务宝物的状态表示为0,那么拿取了价值为0的宝物时,要以另一种情况来跟没拿区分。处理的方法就是将所有宝物的价格+1。longlongdp[55][55][15][15];const......
  • ACwing 最短路算法
    ACwing最短路算法首先介绍一下各个最短路算法的分类及适用情况注意:SPFA算法在部分情况下会被卡一些特殊数据,当被卡时,换用其他对应的算法;下面依次介绍:朴素版dijkstra算法朴素版dijkstra算法适用于稠密图,所以我们只以稠密图的存图方式去介绍;核心思想:首先我们定义一个集合st......
  • ACWing 247.亚特兰蒂斯
    #include<cstdio>#include<cstring>#include<iostream>#include<algorithm>#include<vector>usingnamespacestd;constintN=100010;intn;structSegment{doublex,y1,y2;intk;booloperator<(con......
  • 2024AcWing蓝桥杯集训·每日一题-差分
    1.[AcWing4262.空调]题目描述FarmerJohn的\(N\)头奶牛对他们牛棚的室温非常挑剔。有些奶牛喜欢温度低一些,而有些奶牛则喜欢温度高一些。FarmerJohn的牛棚包含一排\(N\)个牛栏,编号为\(1…N\),每个牛栏里有一头牛。第\(i\)头奶牛希望她的牛栏中的温度是\(p_i\),而现......
  • 地宫取宝
    一、题目描述[蓝桥杯2014省AB]地宫取宝二、问题简析一开始,我采用\(bfs\)进行搜索,出现了超出内存限制的问题。所以,要进行记忆化搜索,重新采用\(dfs\)。2.1暴力搜索令\(dfs(i,j,cnt,val)=\)从\((i,j)\)开始,有几种路线拿到\(k\)件物品(此时已经取了\(cnt\)件......
  • 2024AcWing蓝桥杯集训·每日一题-前缀和
    1.[AcWing562.壁画]题目描述Thanh想在一面被均分为\(N\)段的墙上画一幅精美的壁画。每段墙面都有一个美观评分,这表示它的美观程度(如果它的上面有画的话)。不幸的是,由于洪水泛滥,墙体开始崩溃,所以他需要加快他的作画进度!每天Thanh可以绘制一段墙体。在第一天,他可以自由的......
  • 2024AcWing蓝桥杯集训·每日一题-二分
    1.[AcWing503.借教室]题目描述在大学期间,经常需要租借教室。大到院系举办活动,小到学习小组自习讨论,都需要向学校申请借教室。教室的大小功能不同,借教室人的身份不同,借教室的手续也不一样。面对海量租借教室的信息,我们自然希望编程解决这个问题。我们需要处理接下来\(n\)天......