题目链接:
[HDU 4803]Poor Warehouse Keeper[贪心]
题意分析:
有两个按钮,上面的按钮每按一次,个数增加1,下方的总数增加相应的单价,单价只显示整数部分;下方的按钮每按一次,总数增加1,不影响上方。现在从(1,1)开始,要到达(x,y),问:最少要按多少次按钮?没有答案则输出-1。
解题思路:
上方按钮不管怎么样都得按X - 1次,所以关键是下方的增长让它最快,并且保证最终结果不会超出Y。那么我们就可以事先求出该商品的最高单价:(Y + 1 - eps) / X。然后每一次都尽量让总价达到当前个数可以到达的总价,这样就能保证增长速度是最快的,而且不会超出Y。
个人感受:
知道是求最快增长,不过当时的思考方向是尽快到达最大单价,整个就失败告终。。。。。
具体代码如下:
#include<algorithm>
#include<cctype>
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<set>
#include<sstream>
#include<stack>
#include<string>
#define lowbit(x) (x & (-x))
#define root 1, n, 1
#define lson l, m, rt << 1
#define rson m + 1, r, rt << 1 1
#define ll long long
#define pr(x) cout << #x << " = " << (x) << '\n';
using namespace std;
const int INF = 0x7f7f7f7f;
const int MAXN = 1e6 + 111;
const double eps = 1e-5;
int main()
{
#ifdef LOCAL
freopen("C:\\Users\\apple\\Desktop\\in.txt", "r", stdin);
#endif
double x, y;
while (~scanf("%lf%lf", &x, &y)) {
if (x > y) {
printf("-1\n");
continue;
}
double mx = (y + 1 - eps) / x;
double cur = 1;
int ans = (int)x - 1;
for (int i = 1; i <= (int)x; ++i) {
double target = i * mx;
int add = (int)(target - cur);
cur += add;
ans += add;
cur = cur * (i + 1) / i;
}
printf("%d\n", ans);
}
return 0;
}