首页 > 代码库 > hdu 5802 Windows 10 (dfs)

hdu 5802 Windows 10 (dfs)

Windows 10

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 2191    Accepted Submission(s): 665

Problem Description
Long long ago, there was an old monk living on the top of a mountain. Recently, our old monk found the operating system of his computer was updating to windows 10 automatically and he even can‘t just stop it !!
With a peaceful heart, the old monk gradually accepted this reality because his favorite comic LoveLive doesn‘t depend on the OS. Today, like the past day, he opens bilibili and wants to watch it again. But he observes that the voice of his computer can be represented as dB and always be integer. 
Because he is old, he always needs 1 second to press a button. He found that if he wants to take up the voice, he only can add 1 dB in each second by pressing the up button. But when he wants to take down the voice, he can press the down button, and if the last second he presses the down button and the voice decrease x dB, then in this second, it will decrease 2 * x dB. But if the last second he chooses to have a rest or press the up button, in this second he can only decrease the voice by 1 dB.
Now, he wonders the minimal seconds he should take to adjust the voice from p dB to q dB. Please be careful, because of some strange reasons, the voice of his computer can larger than any dB but can‘t be less than 0 dB.
 
Input
First line contains a number T (1T300000),cases number.
Next T line,each line contains two numbers p and q (0p,q109)
 
Output
The minimal seconds he should take
 
Sample Input
2 1 5 7 3
 
Sample Output
4 4

 

Author
UESTC
 
Source
2016 Multi-University Training Contest 6
 
Recommend
wange2014

 题解:

先尽可能往下降然后升回来,或者尽可能往下降后停然后再往下降,于是就能将问题变成一个子问题,然后dfs就好,需要注意的是由于升也可以打断连续降的功效,所以应该记录停顿了几次,以后上升的时候先用停顿补回来,不够再接着升,时间复杂度O(Tlogq) 

 

#include <bits/stdc++.h>

using namespace std;
const int inf=0x7fffffff;
typedef long long ll;
ll res;
int T;
long long p,q;
long long sum[50];

void dfs(ll x,ll y,ll ti,ll stop)
{
   if (x==y) {res=min(res,ti); return;}

   int k=1;
   while(x-sum[k]>y) k++;

   if (x-sum[k]==y) { res=min(res,ti+k); return;}
   ll up=q-max((ll)0,x-sum[k]);
   res=min(res,ti+k+max((ll)0,up-stop)); //停顿可以替换向上按
   dfs(x-sum[k-1],y,ti+k,stop+1); //停顿次数+1,向下减音量从1开始
   return;
}
int main()
{

    for(int i=1;i<=31;i++)
        sum[i]=(1<<i)-1;

    scanf("%d",&T);
    for(;T>0;T--)
    {
        scanf("%lld%lld",&p,&q);
        if (p<=q) printf("%lld\n",q-p);
        else
        {
            res=inf;
            dfs(p,q,0,0);
            printf("%lld\n",res);
        }
    }
    return 0;
}

 

hdu 5802 Windows 10 (dfs)