#153. 拍卖

#153. 拍卖

话不多说,快上车!

题目描述

一般情况下,拍卖行的拍卖师在拍卖商品的时候都是从低价开始起拍,由买方报价,最后谁出的价格高,商品就归谁所有。但焦作有个拍卖行,拍卖师在拍卖商品时正好相反:总是从高价开始起拍,如果没有人举成交牌就降价,而且拍卖师在降价时还有规律:假如第i次报价为w元,那么第i+1次报价为w-a或者w-b元,如果降到p元时,你认为价格合适,赶快第一个举成交牌,你就花p元买下了商品。

题目任务:拍卖师把商品从w元降到p元的方法总数。

注意要点:测试数据中方法总数不超过MAXlongint

题目类型:

    这是一道十分典型的递归题目。。。。。。

大体思路:

既然是一道递归题目,过程函数不能少。这道题目就是已知W元,把W元每次递归分别减去a元或者b元,求有多少种不同方法得到P元。但关键是这道题的数据还很大,用普通的裸搜肯定是过不去的。所以我们就要用到函数来不断递归不同的种数。

部分代码:

Voidwork(int head,int tail)

{

    If(head==tail)

    {

        S++;

    }

Else

{

        Work(head-a,tail);

        Work(head-b,tail);

}

}

如题意,从w元有很多方法可以降成p元,但不变的是每一次只能降a元或b元,所以,我们可以定义一个递归函数work(Inthead,int tail),head代表当前的拍卖金额状态,所以head一开始就是w,tail代表结束时的金额,即为p。tail不定义也可以,定义了方便理解。看起来仿佛很简单的样子???

为什么是MLE?!这样显然是不行的,编译后什么答案也输不出来,提交oj的结果是MLE,显然是有大问题了,再看看代码吧。

显然,这个代码是不行的,因为他没有定义递归的边界。即使是很简单的题目,使用递归仍然该注意应有的细节。在很复杂的dfs题中,需要判断的条件更多,学会及时理解需要处理的边界,必须从简单的题做起。

代码更改:

Voidwork(int head,int tail)

{

    If(head==tail)

    {

        S++;

    }

Else

{

    If(head<tail)

    {

       Return;

    }

    Else

    {

            Work(head-a,tail);

            Work(head-b,tail);

        }

}

}

这样就可以了吗???当然不行。

这就是我们所谓的爆搜代码了。好吧,这就是爆搜代码,是会超时的。我们必须对代码进行优化,其实加个记忆化就行了。那就加记忆化吧。

备注:记忆化--顾名思义,就是对一些计算后的结果进行记录,然后直接调用即可,避免重复计算。也是空间换时间的思想。

终极代码:

#include<bits/stdc++.h>

using namespace std;

long long w,p,a,b,c[1000010];//把每一种已有过的情况储存起来

int work(int head,int tail)

{

      if(tail>head) return 0;//如果超过接线就退出

      if(tail==head) return 1;//相等就返回1

      if(c[head]>0) return c[head];//进行判断

      c[head]=work(head-a,tail)+work(head-b,tail);//情况种数相加

      return c[head];//返回值

}

int main()

{

      cin>>w>>p>>a>>b;

      work(w,p);

      cout<<c[w]<<endl;

      return 0;

}

    递归最重要就是一定要注意很多细节和套路。。。。。。
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值