HDU

来源:互联网 发布:淘宝团队管理制度 编辑:程序博客网 时间:2024/06/06 01:11

题目链接


题意:


调节音量s到t,上升音量每秒只能上升1,下降音量每秒为2*x,x为上一次下降的音量,如果下降时休息或者上升音量则x置为1,音量最低为0


思路:


这种看似好想,怎么写怎么wa的题最气人。

首先 s <= t  直接一直上调就好了,调  t-s次

如何快速的调回去呢?有两种方法: 一种是一直往下调调到小于t再往上调,一种是调到在调一次就要小于t了,歇一会从1开始再继续往下调.


对于每一个s'到t都有这些方法.由于我们知道 停顿一下再继续减,和往上调1次再减是等价的,都是使得减从1开始,为了节省步数,发现什么时候加,对结果无影响,所以我们可以在停顿的时刻进行上调来节约步数.两个过程维护一下最小值

#include<bits/stdc++.h>using namespace std;const int maxn = 50;typedef long long ll;ll sum[maxn];ll p,q;void init(){sum[0] = 0;sum[1] = 1;ll res = 1;for(int i = 2;i <= 33;++i){res *= 2;sum[i] = sum[i-1] + res;}return ;}ll dfs(ll res,ll s,ll stop){if(res == q) return s;int cur = 0;while(res - sum[cur] > q) cur++;if(res - sum[cur] == q) return s+cur;ll up =  q - max((ll)0,res-sum[cur]);ll step = cur + max((ll)0,up-stop);return min(s+step,dfs(res-sum[cur-1],s+cur,stop+1));}int main(){int _;cin>>_;init();while(_--){scanf("%lld %lld",&p,&q);if(q >= p){printf("%lld\n",q-p);}else{ll ans = dfs(p,0,0);printf("%lld\n",ans);}}return 0;}





原创粉丝点击