Right now she actually isn't. But she will be, if you don't solve this problem.
You are given integers n, k, A and B. There is a number x, which is initially equal to n. You are allowed to perform two types of operations:
- Subtract 1 from x. This operation costs you A coins.
- Divide x by k. Can be performed only if x is divisible by k. This operation costs you B coins.
The first line contains a single integer n (1 ≤ n ≤ 2·109).
The second line contains a single integer k (1 ≤ k ≤ 2·109).
The third line contains a single integer A (1 ≤ A ≤ 2·109).
The fourth line contains a single integer B (1 ≤ B ≤ 2·109).
Output a single integer — the minimum amount of coins you have to pay to make x equal to 1.
9
2
3
1
6
5
5
2
20
8
19
3
4
2
12
In the first testcase, the optimal strategy is as follows:
- Subtract 1 from x (9 → 8) paying 3 coins.
- Divide x by 2 (8 → 4) paying 1 coin.
- Divide x by 2 (4 → 2) paying 1 coin.
- Divide x by 2 (2 → 1) paying 1 coin.
The total cost is 6 coins.
In the second test case the optimal strategy is to subtract 1 from x 4 times paying 8 coins in total.
题意就是:给一个数,有两种操作,除以k(如果可以整除的话),减一。分别花费a,b硬币每次。问你怎么样最省钱,使得n变为1。
下面来讲讲我超级水的思路吧,真的丢人,800多ms险过。大概也算是贪心的题目,但是还有很多细节问题。
就模拟这个过程,①如果可以整除,就整除和相减比较一下,(注意是把 相减是要减到整除后的结果那里,这样比才有意义),
②不能整除,就减1,一直到可以整除的地方。 当然,如果只这样写,肯定超时,毕竟题目数据到了1e9。
所以要加一些条件,比如①中,如果相减划算一些,那么后面的全部要执行相减操作,直到1,因为越往后,相除的性价比越低,因为n越来越小,n-n/k,就越来越小。
然后②中,不能单纯的这样写 一、while(n%k != 0) n--; 题目有1e9呀,二、我们还可以累加k,直到刚好不超过n,这时候就得到一个数,可以被k整除,而且隔n最近。
一和二其实各有各的用处,当k比较小的时候,用一,k比较大的时候,用二。
所以说,这道题被我写毁了,虽然勉强过了。
另外,还有一个WA的地方是,会超出int 范围,不要以为ans用long long 声明就行了,稍微写错一点,就会wa,建议所以变量全部改成long long型,因为其中涉及到了乘法,虽然题目给的数据只有1e9,但是乘起来却会超int。
代码:
#include <iostream>
using namespace std;
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<queue>
#include<vector>
#define inf 0x3f3f3f3f
typedef long long ll;
ll n,k,a,b;
ll f1(ll x)
{
while( x%k != 0 && x>1 )
x--;
return x;
}
ll f2( )
{
ll i = k<<1;
while( i < n )
{
i += k;
}
return i-k;
}
int main()
{
while( scanf("%I64d %I64d %I64d %I64d",&n,&k,&a,&b) == 4 )
{
ll ans = 0;
while( n > 1 )
{
if( n < k )
{
ans += (n-1)*a;
break;
}
if( n%k == 0 )
{
if( b >= ( n-n/k )*a )
{
ans += (n-1)*a;
break;
}
else
{
ans += b;
n = n/k;
}
}
else
{
int temp = n;
if( n <= 1e7 )
n = f1(n);
else n = f2();
//ans += (temp-n)*a;
ans += (temp-n)* a;
}
}
printf("%I64d\n",ans);
}
return 0;
}
/*
1999324353
978435356
1
978435356
1020888998
*/