hdu 5802 windows 10

题意:把音量从p调到q,

若 q >= p,一直按着每次音量上升1

若 q < p ,每次按着的那一秒下降1,接下来一秒下降2,4,8....(2x),x是前一秒下降的值。中途可以选择按键停止或up上升


求 p  -> q的最小时间。

思路:枚举 2^tx-1 > q - p,选择降到q的下方或上方,然后逼近。


做多校时由于一直想着按up要加+1所以做了两边dfs,一直tle,看了题解才恍然大悟:

以下是看过标程写的代码:记录stop,停下多少次,不管有没有up,如果最终跳到q的下方,所有向上+1的作用都可以和从q下面到q的时间抵消。(所以不用考虑一开始先向上再下来)

#include <iostream>
#include <cstdio>

using namespace std;

typedef long long ll;

ll dfs(int now ,int goal,int stop,ll ans){
    if(now == goal) return ans;
    int tx = 0;
    while(now - (1<<tx) + 1 > goal) tx++;
    //与q点重合
    if(now - (1<<tx)+1 == goal) return ans + tx;
    //在q点下方
    ll dis = goal - max(0LL,(ll)now-(1<<tx)+1);
    ll tm = tx + max(0LL,(ll)(dis - stop));
    //在q点上方
    return min(ans + tm ,dfs(now - (1<<(tx-1)) + 1 ,goal,stop+1,ans+tx));

}
int main()
{
    //freopen("in.txt","r",stdin);
    int p,q,t;
    scanf("%d",&t);
    while(t--){
        scanf("%d%d",&p,&q);
        if(q>=p){
            printf("%lld\n",(ll)(q - p));
        }
        else{
            printf("%lld\n",dfs(p,q,0,0LL));
        }

    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值