hdu5802
题目
就是要求调到目标音量的最小步数,如果向上调的话每次只能一步,向下的话,如果上一次也是像下,这次是上次的*2,如果停顿或者向上的话就是1步。
思路
朴素的bfs会超时,应该是贪心,以尽快的逼近目标位置为目的,同时注意,向上走和停顿是可以合并的,最后向上赶的步数可以抵消掉之前下降过程中停顿的次数,细节看代码。
代码
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#include <queue>
using namespace std;
typedef long long ll;
ll n,m;
ll dfs(int p,int q,int step,int res)
{
int x=0;
if(p==q) return step;
while(p-(1LL<<x)+1>q) x++;
if(p-(1LL<<x)+1==q) return step+x;
ll up=q-max(0LL,p-(1LL<<x)+1);
ll temp=max(0LL,up-res);
return min(x+temp+step,dfs(p-(1LL<<(x-1))+1,q,step+x,res+1));
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
scanf("%I64d %I64d",&n,&m);
if(n<=m)
{
printf("%I64d\n",m-n);
}
else
printf("%I64d\n",dfs(n,m,0,0));
}
return 0;
}