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=1的情况一直没有过,最后就放弃了,其实当时离正确答案就差一点点了,很遗憾,没有把情况考虑清楚。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<stdlib.h>
#include<math.h>
#include<iostream>
#include<queue>
#include<map>
#include<vector>
#include<stack>
#define inf 0x3fffffff
using namespace std;
typedef long long LL;
int n,k,b;
LL a,ans;
int main()
{
while(~scanf("%d%d%lld%d",&n,&k,&a,&b))
{
ans=0;
if(k==1||n<k)//当n<k或者k=1时只能进行减一操作
{
printf("%lld\n",(n-1)*a);
continue;
}
while(n>1)
{
if(n%k)//n不能整除k时只能减一
{
LL t=n%k;
if(n<k) t--;//不能减到0,只能减到1
n-=t;
ans+=a*t;
}
else//若可以整除那就要判断减一操作和整除操作哪个花的硬币更少
{
if((n-n/k)*a<b) ans+=(n-n/k)*a;
else ans+=b;
n/=k;
}
}
printf("%lld\n",ans);
}
}