您的位置:首页 > 其它

HDU 4803 Poor Warehouse Keeper 贪心 二分搜索

2014-09-30 21:55 253 查看
题意:有一个机器,上面有两个数字:数量和总价格。初始时,数量和总价格都是1,平均价格严格为1.0。数量和总价格分别有一个按钮。

按下数量的按钮,会使数量加1,同时,总价格也会上升,最终得到的值时平均价格乘以数量。但是,这个机器不会显示小数点以后的数字。

按下总价格的按钮,会使总价格上升1,同时,也会改变平均价格。

现在的问题是:给出目标的数量和总价格,问,至少按几次按钮可以到达这样的操作。

思路:我们可以发现有以下的性质:

1.平均价格不会下降。

2.只要真实的总价格不大于目标的总价格1.0,机器就会显示目标价格;

3.在数量少的时候,提高总价格,会在后来产生更大的价格提升。

4。目标数量特别少,最多只有10个。

利用性质3,我们可以得到,在每个数量下,尽可能的提高总价格会使操作的数量减少,这就可以得到最优解。

利用性质2,我们可以得到,在每个数量下,提高总价格的上界。这样,我们就可以利用边界,直接二分,求得最多且满足题意的操作数目。

利用性质4,我们可以直接从小到大模拟。

利用性质1,我们可以判断是否有解。

代码如下:

#include <cstdio>
#include <cmath>

using namespace std;

int main(void)
{
int x,y;
while(scanf("%d %d", &x,&y) != EOF){
if(y < x){
puts("-1");
continue;
}
double nx = 1.0, ny = 1.0;
int ans = 0;
while(true){
int lb = 0, ub = y;
while(lb + 1 < ub){
int mid = (lb + ub) >> 1;
//printf("%d\n",mid);
double tmp = ny + mid;
if(tmp / nx * x - y < 1.0)
lb = mid;
else
ub = mid;
}
ny += lb;
ans += lb;
double avera = ny / nx;
if(fabs(nx - x) < 1e-6) break;
nx += 1.0;
ans += 1;
ny = avera * nx;
printf("%f %f\n",nx,ny);
}
printf("%d\n",ans);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: