HDU 5802 Windows 10

传送门

Windows 10

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


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 $2x$ 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 (1\le T\le 300000)$,cases number.
Next $T$ line,each line contains two numbers $p$ and $q (0\le p,q\le 10^9)$.

 

 

Output
The minimal seconds he should take
 

 

Sample Input
2
1 5
7 3
 

 

Sample Output
4
4
 

 

Author
UESTC
 

 

Source

 Solution:
首先明确题意:
the voice of his computer can larger than any dB but can't be less than $0$ dB.
这句话的意思是: 如果当前按一次down会导致音量减到负值, 那么按下down后, 音量就会变成0, 不能理解成: 当前不能按down.
$p\le q$的情况是trivial的, 下面考虑 $p>q$.
初步分析可以看出:
1. 一连串的down可以看成一个down, 下文中的的down指的都是一连串的down.
2. rest连接两个down, 然而这并没有什么用.
3. up是为了更好地down, 这个结论比较有用:
我们可以把up操作都放在最后进行. 之前的操作模式就是
down rest down rest ... down 一直down到q或q以下, 再up到q, 注意最后的up可以用之前的rest操作代替一部分或全部.

但是分析到这里暴力的复杂度仍然是不能承受的.
我们可以注意到一个贪心策略:
每次都尝试down到小于等于q然后再up回来, 或者down到大于q的最小值, rest一步继续down.
这个策略的正确性我还不会证.

Implementation
#include <bits/stdc++.h>
using namespace std;

int res, p, q, s[32], T;

void dfs(int x, int p, int sub){
    if(p+sub>=res) return;
    int i=lower_bound(s, s+32, x)-s, r=s[i]-x;
    res=min(res, p+sub+i+max(0, min(q, r-p)));
    if(r) dfs(x-s[i-1], p+1, sub+i-1);
}


int main(){
    for(int i=0; i<32; i++)
        s[i]=(1LL<<i)-1;

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

 

 
posted @ 2016-08-05 11:04  Pat  阅读(236)  评论(0编辑  收藏  举报