hdu 5802 windows 10
题意:判断从p -> q所需要的最少的步骤,往上调高只能一步一步调,而调低可以是上一步的两倍,然而想要中断这种升高的话就得在原地休息一下或者向上升一步;
思路:直接递归就行了。不过要考虑一点,我可以把中间停顿的秒数最为后面低于q之后要进行相加的次数抵消一点,也就是中间的停顿可以作为相加使用;
还有一点,不能减到小于0,也就是说最小减到0;
代码;
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define MOD 21474936
const int maxn = 32;
ll a[maxn];
void Init()
{
a[1] = 1;
for(ll i = 2,temp = 2; i < maxn ; i ++,temp *= 2)
{
a[i] = a[i - 1] + temp;
}
}
int dfs(ll p,ll q,ll k)
{
int t;
ll length = p - q;
if(length <= 0)
{
return max(-length,k);
}
for(int i = 1; i < maxn ; i ++)
{
if(a[i] > length)
{
t = i;
break;
}
}
t --;
if(a[t] == length)
return t + k;
if(p - a[t + 1] < 0)
return min(t + 1 + dfs(0,q,k),t + dfs(p - a[t],q,k + 1));
return min(t + 1 + dfs(p - a[t + 1],q,k),t + dfs(p - a[t],q,k + 1));
}
int main()
{
Init();
int Tcase;
scanf("%d",&Tcase);
for(int ii = 1; ii <= Tcase; ii ++)
{
ll p,q;
scanf("%I64d%I64d",&p,&q);
if(p <= q)
{
cout << q - p <<endl;
continue;
}
int ans =dfs(p,q,0);
cout << ans << endl;
}
return 0;
}