题目描述
解题思路
采用动态规划的思路解决这一问题。
动态规划的关键思路是找到子问题的形式和在子问题中解决问题的同一逻辑。
- 子问题的定义
在这一题中,我们的子问题形式是,在给定武力值数组和金币数组的前提下,由当前所处的位置以及当前所拥有的被保护的战斗值,即可定义一个子问题。
- 处理逻辑
如果当前的被保护战斗值小于怪兽的战斗值,则返回当前 金币数+(位置+1, 被保护战斗值+当前怪兽战斗值)的结果,即在这一关选择话费金币,买通怪兽。
如果当前的被保护战斗值大于怪兽的战斗值,则在这一关有两种选择,要么花费金币,要不不花,返回更小的那一个即可。
代码
import java.util.HashMap;
import java.util.Scanner;
public class Main{
static int n;
static long[] fightVals;
static int[] goldVals;
static int runTimes = 0;
static HashMap<String,Integer> cache;
public static void main(String[]args){
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
fightVals = new long[n];
goldVals = new int[n];
for (int i = 0; i < n; i++) {
fightVals[i] = sc.nextLong();
}
for (int i = 0; i < n; i++) {
goldVals[i] = sc.nextInt();
}
cache = new HashMap<>();
System.out.println(minGoldVal(0, 0));
}
public static int minGoldVal(int curPos, long curProtect){
String caseStr = curPos + "_" + curProtect;
if (cache.containsKey(caseStr)){
return cache.get(caseStr);
}
if (curPos==n-1){
if (fightVals[curPos] > curProtect){
return goldVals[curPos];
}else {
return 0;
}
}
if (fightVals[curPos] > curProtect){
int result = goldVals[curPos] + minGoldVal(curPos+1, curProtect+fightVals[curPos]);
cache.put(curPos + "_" + curProtect , result);
return result;
}else {
int result = Math.min(minGoldVal(curPos+1, curProtect),
goldVals[curPos] + minGoldVal(curPos+1, curProtect+fightVals[curPos]));
cache.put(curPos + "_" + curProtect , result);
return result;
}
}
}