力扣 2212. 射箭比赛中的最大得分

题目来源:https://leetcode-cn.com/problems/maximum-points-in-an-archery-competition/

大致题意:
给射箭数,和 A 的在 0 ~ 11 得分对应的区域射中数目的数组,如果 B 想拿对应得分区域的分值,就需要在对应区域的射中数目大于 A,求出 B 在相同射箭数的情况下如何获得最大得分

思路

若 B 想在某个区域得分,最优的选择是在对应区域射中 A 射中的数目 + 1

因为深度最大为 12,可以通过 DFS + 回溯 枚举所有可能,求出最大得分

DFS + 回溯
  1. 倒序 DFS
  2. 每次枚举 B 是否选择获取该区域得分,若选择获取该区域得分,还要在方法结束后回溯状态

注意边界条件:

  • 枚举到得分区域 0 时,或者剩余射箭数为 0 时,终止枚举,更新最大得分

代码:

public class MaximumBobPoints {
     int[] ans;     // B 的射箭数对应的数组
     int max;  // B 的最大得分
     public int[] maximumBobPoints(int numArrows, int[] aliceArrows) {
          max = 0;
          int n = aliceArrows.length;
          int[] bobArrows = new int[n];
          // 开始 DFS
          dfs(aliceArrows, bobArrows, n - 1, numArrows, 0);
          return ans;
     }

     /**
      * 
      * @param aliceArrows    A 的射箭数对应的数组
      * @param bobArrows      B 的射箭数对应的数组
      * @param idx  目前枚举的得分区域索引
      * @param num  目前 B 的剩余射箭数
      * @param sum  目前 B 的得分
      */
     public void dfs(int[] aliceArrows, int[] bobArrows, int idx, int num,int sum) {
          if (idx < 0 || num < 0) {
               return;
          }
          // 如果剩余射箭数为 0,或者枚举到 0 得分区域
          if (num == 0 || idx == 0) {
               // 更新最大得分
               if (max < sum) {
                    max = sum;
                    ans = Arrays.copyOf(bobArrows, bobArrows.length);
                    ans[0] = num;
               }
               return;
          }
          // 不在当前区域射箭
          dfs(aliceArrows, bobArrows, idx - 1, num, sum);
          // 在当前区域射箭
          if (num - aliceArrows[idx] >= 1) {
               // 更新数组
               bobArrows[idx] = aliceArrows[idx] + 1;
               // 更新剩余射箭数
               num -= aliceArrows[idx] + 1;
               // 更新目前得分
               sum += idx;
               dfs(aliceArrows, bobArrows, idx - 1, num, sum);
               // 回溯
               bobArrows[idx] = 0;
          }
     }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

三更鬼

谢谢老板!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值