斗破苍穹算法版—萧炎的成长之路(一)

前言

在这里插入图片描述
「作者主页」雪碧有白泡泡
「个人网站」雪碧的个人网站
「推荐专栏」

java一站式服务
前端炫酷代码分享
uniapp-从构建到提升
从0到英雄,vue成神之路
解决算法,一个专栏就够了
架构咱们从0说
数据流通的精妙之道

请添加图片描述

主角介绍

萧炎是一位虚构角色,出自于中国作家天蚕土豆的小说《斗破苍穹》。在小说中,萧炎是一个年轻的天才炼药师和斗气修炼者,他经历了许多困难和挑战,通过不断努力和智慧,最终成为了强大的存在。
在这里插入图片描述

动态规划

动态规划(Dynamic Programming)是一种常用的算法设计方法,它通常用于解决具有重叠子问题和最优子结构性质的问题。虽然萧炎并非现实存在人物,但我们可以他的故事与动态规划的思想联系起来,以便更好地理解动态规划的概念。

故事背景

在小说中,萧炎面临着许多困和敌人,他需要不断提升自己的实力以保护自己和身边的人。
这可以类比为动态规划中的问题,其中萧炎需要找到一条最优的路径或策略来解决问题。动态规划的核心思想是将原问题分解为若干个子问题,并保存子问题的解,避免重复计算。似地,萧炎在修炼斗和炼药过中也会遇到各种子问题,他会据自己的经验和知识来决这些问题,并将解决方案保存下来以备将来使用。
在这里插入图片描述

题目:

萧炎在修炼斗技和炼药程中需要消耗不同数量的资源,他希望通过合理安排资源的使用,使得自己的实力提升最快。已知萧炎拥有一定数量的资源,每次修炼斗技或炼药都需要消耗一定数量的资源,而每次修炼斗技或炼药所获得的实力提升也是不同的。请问,萧炎应该如何安排资源的使用,才能使得实力提升最快?

输入:

一个整数n,表示萧炎拥有的资源总量。 两个长度为n的数组a和b,分别表示修斗技和炼药过程中每次消耗的资源数量。

两个长度为n的数组c和d,分别表示修炼斗技和药过程中每次得的实力提升值。
输出一个整数,表示萧炎通过合理安排资源使用所能达到的最大实力提升值。
示例:
输入: n = 3 a = [1, 2, 3] b = [2,3, 4] c = [5, 10, 15] d = [10, 20, 30]

输出: 60

解释:
萧炎拥3个资源,每次修炼斗技和炼药过程中分别消耗1、2、3个资源。每次修炼斗技和炼药过程中分别获得10、20、30的实力提升值。为了使实力提升最快,炎可以选择使用1个资源修炼斗,使用第2个资源炼药,使用第3个资源修炼斗技。这总共消耗的资源为1+2+3=6,总共获的实力提升值为10+20+30=60,是最优的方案。

解决方案

  1. 我们可以定义一个二维数组dp,其中dp[i][j]表示在前i个资源使用j个资源时所能达到的最大实力提升值。

  2. 首先,我们需要初始化dp数组。当没有资源可用时,无论使用多资源,实力提升值都为0因此dp[0][j] = 0。当没有使用任何资源时,实力提升值也为0,dp[i][0] = 0。

  3. 然后,我们可以使用状态转移方程来更新dp数组。对于第i个资源,我们有两种选择:使用它修炼斗技或者炼药过程。如果选择修炼斗技,那么实力提升值为dp[i-1][j-1]+ c[i-1],即i-1个资源中使用j-1个资源时的最大实力提升值加上第i个资源修炼斗技所得的实力提升值。如果选择炼药过程,那么实力提升值为dp[i-1][j] + d[i-1],即前i-1个资源中使用j个资源时的最大实力提升值加上第i个资源炼药过程所得的实力提升值。我们需要取这两种选择中的较大值作为dp[i][j]的值。

  4. 最后dp[n][n]即为所求的结果,表示在n个资源中使用n个资源时所能达到的最大实力提升值。

以下是Java实现代码:

public class Main {
    
    
    public static void main(String[] args) {
    
    
        int n = 3;
        int[] a = {
    
    1, 2, 3};
        int[] b = {
    
    2, 3, 4};
        int[] c = {
    
    5, 10, 15};
        int[] d = {
    
    10, 20, 30};

        int[][] dp = new int[n + 1][n + 1];

        for (int i = 0; i <= n; i++) {
    
    
            dp[i][0] = 0;
            dp[0][i] = 0;
        }

        for (int i = 1; i <= n; i++) {
    
    
            for (int j = 1; j <= n; j++) {
    
    
                if (j >= a[i - 1]) {
    
    
                    dp[i][j] = Math.max(dp[i - 1][j - a[i - 1]] + c[i - 1], dp[i][j]);
                }
                if (j >= b[i - 1]) {
    
    
 dp[i][j] = Math.max(dp[i - 1][j - b[i - 1]] + d[i - 1], dp[i][j]);
                }
            }
        }

        System.out.println[n][n]);
    }

状态转移方程

此外,动态规划还涉及到状态转移方程的定义。在小说中,萧炎通过不断修炼和战斗,逐渐提升自己的实。这可以看是一个状态转移过程,每状态都与前一个状态相关联。类似地,在动态规划中,我们通常定义一个状态移方程来描述问题的最优子结构,从而导出整个问题的优解。

题目

在这里插入图片描述

题目:假设萧炎在修炼过中,他可以选择进行不同的训练活动来提升自己的实力。每个训练活动都有一个对应的消耗和收益值。萧炎的目标是通过选择适当的训练活动,使得他的实力值达到最大化。请设计一个动态规划算法,计算出萧炎能够达到的最大实力值。

输入:

  • 一个整数数组costs,表示每个训练活动的消耗值,其中 costs[i] 表示第 i 个训练活动的消耗值。
  • 一个整数数组benefits,表示每个训练活动的收益值其中 benefits[i] 表示 i 个训练活动的收益值。
  • 一个整数target,表示萧炎希望达到的目标实力值。

输出:

  • 一个整数,表示萧炎能够达到的最大实力。

解决方案

以下是使用Java语言实现该动态规划问题的代码:

public class WarriorTraining {
    
    
    public static int maxStrength(int[] costs, int[] benefits, int target) {
    
    
        int n = costs.length;
        int[][] dp = new int[n + 1][target + 1];

        for (int i = 1; i <= n; i++) {
    
    
            int cost = costs[i - 1];
            int benefit = benefits[i - 1];

            for (int j = 0; j <= target; j++) {
    
    
                if (j >= cost) {
    
    
 dp[i][j] = Math.max(dp[i - 1][j],[i - 1][j - cost] + benefit);
                } else {
    
    
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }

        return dp[n][target];
    }

 public static void main(String[] args) {
    
    
        int[] costs = {
    
    2, 3, 4, 5};
        int[] benefits = {
    
    3, 4, 5, 6};
        int target = 10;

        int maxStrength = maxStrength(costs, benefits, target);
        System.out.println("萧炎能够到的最大实值为: " + maxStrength);
    }
}

在上述代码中我们使用二维数组dp来记录状态转移过程。其中dp[i][j]表示在前i个训练活动中,达到实力值j所能获得的最大收益。通过遍历每个训练活动和目标实力值的组合,根据状态转移方程dp[i][j] = max(dp[i-1][j], dp[i-1][j-cost]+benefit)更新dp数组。最终,dp[n][target]即为萧炎能够达到的最大实力值。

在给定的示例中,萧炎有4个训练活动,对应的消耗值为{2, 3, 4, 5},收益值为{3, 4, 5, 6},目标实力值为10。运行上述代码,输出结果为萧炎能够达到的最实力值为:11,表示战士可以通过选择第1个和第4个训练活动达到实力值11的最大收益。

结语

总之,虽然萧炎的故事并非真实存在,但我们可以将他的历与动态划的思想相联系,以更好地理解和应用动态规划算法。动态规划的核心思想是将复杂的问题分解为简单的子问题,并通过保存子问题的解来避免重复计算,从而找到问题的最优解。

猜你喜欢

转载自blog.csdn.net/Why_does_it_work/article/details/131819602
今日推荐