1. 程式人生 > >【貪心】hdu4803 Poor Warehouse Keeper

【貪心】hdu4803 Poor Warehouse Keeper

暴力 由於 house return () 不能 當前 但是 class

題意:一開始有1個物品,總價是1。你的一次操作可以要麽使得物品數量+1,總價加上當前物品的單價。要麽可以使得總價+1,物品數量不變。問你最少要幾次操作從初始狀態到達有x個物品,總價是y的狀態。這裏的y可以有小數點後的部分,會抹去。

如果x>y,顯然無解。

因為不管怎樣操作,物品的單價是單調不下降的。所以一個naive的貪心策略是先用第二種操作,將物品提升到最大的可能單價(<(y+1)/x),然後再用第一種操作操作到不能再操作為止,剩余的部分用第二種補齊。然而這是不對的。

我們發現,第一種操作,使得單價不改變,但是會使得第二種操作下,單價上升的斜率降低了,於是,我們每次先用第二種操作盡力將物品提升到當前最大的可能單價,然後用一下第一種操作,這時沒準就能再用用第二種操作提升單價了,使得後續操作效率提高。由於x<=10,所以可以暴力模擬。

剩余的零散操作補齊即可。

#include<cstdio>
#include<algorithm>
#include<cmath>
const double eps=0.0000001;
using namespace std;
int x,y;
int main(){
    while(scanf("%d%d",&x,&y)!=EOF){
        if(x>y){
            puts("-1");
            continue;
        }
        int xnow=1,ans=0;
        double ynow=1.0;
        while(xnow<x){
            double t=(double)(y+1)*(double)xnow/(double)x;
            ans+=(int)(t-eps-ynow);
            ynow+=(double)(int)(t-eps-ynow);
            ++ans;
            ynow+=ynow/(double)xnow;
            ++xnow;
        }
        printf("%d\n",ans+y-(int)(ynow+eps));
    }
    return 0;
}

【貪心】hdu4803 Poor Warehouse Keeper