青训营X豆包MarsCode 技术训练营回溯法 | 豆包MarsCode AI 刷题

110 阅读3分钟

回溯法

小F的超市购物策略
1.题目思路

利用深度优先搜索(DFS)算法来解决小F的超市购物策略问题,通过递归地探索所有可能的购买组合,同时遵守超市的优惠活动规则,即购买一个商品后下一个商品可以半价购买,但如果下一个商品半价,则再下一个商品必须原价购买。在遍历过程中,代码维护一个全局变量maxlove来记录找到的最大喜爱度总和,每次递归时都会尝试三种情况:以半价购买当前商品、以原价购买当前商品以及跳过当前商品,同时更新总花费和喜爱度总和。当遍历到达叶子节点或超出预算时,会回溯并尝试其他购买路径,最终返回在给定预算下能够获得的最大喜爱度总和。

2.详细方法

初始化: 定义一个全局变量maxlove,用来存储遍历过程中找到的最大喜爱度总和,初始值为0。

DFS函数:- 定义一个递归函数dfs,它尝试所有可能的购买组合,并在遍历过程中更新maxlove

DFS逻辑:

  • 终止条件:如果当前索引i等于商品总数n,或者总花费t超过预算x,则终止递归。
  • 回溯处理:如果t超过x,说明最后购买的商品超出预算,需要撤销这次购买,即从love中减去该商品的喜爱度,从t中减去该商品的价格。
  • 更新最大喜爱度:如果当前的喜爱度总和love大于全局变量maxlove,则更新maxlove

购买决策

  • 半价购买:如果上一个商品是原价购买的(half为0),则当前商品可以半价购买。更新总花费tt + a[i] / 2,更新喜爱度总和lovelove + b[i],并将half标志设置为0,表示下一个商品必须原价购买。

  • 原价购买:如果上一个商品是半价购买的(half为1),或者当前商品不能半价购买,则以原价购买。更新总花费tt + a[i],更新喜爱度总和lovelove + b[i],并将half标志设置为1,表示下一个商品可以半价购买。

  • 跳过购买:无论是否半价,都可以尝试跳过当前商品,不进行购买,保持tlove不变,并将half标志设置为0。

更新最大喜爱度:在DFS遍历过程中,如果当前的喜爱度总和love大于全局变量maxlove,则更新maxlove

返回结果:在solution函数中,返回maxlove的值,即在给定预算下能够获得的最大喜爱度总和。

3.代码实现
#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<iomanip>
#include<queue>
#include<stack>
#include<vector>
#include<set>
#include<map>
#include <functional>
using namespace std;
typedef long long int ll;
 
int maxlove=0;
 
void dfs(int i,int t,int love,int half,int n,int x,std::vector<int> a, std::vector<int> b){
    if(i==n || t>x){
        if(t>x){
            love-=b[i-1];
            t-=a[i-1];
        }
        if(love>maxlove){
            maxlove=love;
            return;
        }
        return ;
    }
    if(half==1){
        dfs(i+1,t+a[i]/2,love+b[i],0,n,x,a,b);
    }
    else{
        dfs(i+1,t+a[i],love+b[i],1,n,x,a,b);
        dfs(i+1,t+a[i],love+b[i],0,n,x,a,b);
    }
    dfs(i+1,t,love,0,n,x,a,b);
}
 
int solution(int n, int x, std::vector<int> a, std::vector<int> b) {
    // write code here
    maxlove=0;
    dfs(0,0,0,0,n,x,a,b);
    //cout << maxlove << "\n";
    return maxlove;
}


int main() {
    std::cout << (solution(4, 7, {2, 2, 6, 2}, {3, 4, 5, 1}) == 12) << std::endl;
    std::cout << (solution(3, 10, {4, 4, 4}, {2, 3, 5}) == 10) << std::endl;
    std::cout << (solution(5, 8, {2, 4, 4, 6, 2}, {1, 2, 3, 4, 5}) == 10) << std::endl;
}