HDU 4803 Poor Warehouse Keeper 贪心 二分搜索

题意:有一个机器,上面有两个数字:数量和总价格。初始时,数量和总价格都是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;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值