题目描述
解法
采用了递归的解法由于每次遇到怪兽,先不论打不打过,都有两种选择,贿赂与不贿赂,即会导致出现两种路线。于是通过递归调用,生成2N-1条路线。一次递归方法中,分别计算贿赂与不贿赂这两条路线的花费金币数,比较后返回花费最少的路线所需的金币数。由于此方法类似于穷举算法,为了减少计算量,走到某一步时,若怪兽武力值大于energy_sum时,直接截断返回整数的最大值INT_MAX,这样可以便于比较输出最小值。最后递归的结束条件是,当走过最后一直怪兽时返回最终的花费。
代码
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
int attack(vector<int>& energy, vector<int>& money,int n, int index,long energy_sum, long money_sum)
{
if (energy[index] > energy_sum)
return INT_MAX;
++index;
if (index == n)
return money_sum;
//第一条路线,默认贿赂怪兽,递归调用下一步
int sum1= attack(energy, money, n, index, energy_sum + energy[index], money_sum + money[index]);
//第二条路线,默认不贿赂怪兽,递归调用下一步
int sum2 = attack(energy, money, n, index, energy_sum, money_sum);
return min(sum1, sum2);
}
int main() {
int n = 3;
//vector<int> energy = { 1,2,4,8 };
//vector<int> money = { 1,2,1,2 };
//vector<int> energy = { 8, 5, 10};
///vector<int> money = { 1,10,2 };
vector<int> energy = { 8, 5, 10};// 怪兽的武力值
vector<int> money = { 1,1,2 }; // 贿赂当前怪兽所需要的金币
// 默认贿赂第一只怪兽所得到的能量为energy[0]
// 所需要花费的金币为money[0] 每递归一次都会分出两种路线:贿赂or不贿赂
int x = attack(energy, money, n, 0, energy[0], money[0]);
cout << x << endl;
return 0;
}
总结
当时是舍友腾讯笔试的题,当时舍友只AC了80%,然后自己想复杂了 想用递归加动态规划就把自己绕晕了,事实证明还是不要把题想的太复杂。多刷题,还是经验太少
参考了DarkFlameMaster_的代码
原文:https://blog.csdn.net/xz313889179/article/details/89058276