题面和链接
940B
B. Our Tanya is Crying Out Loud
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
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.
What is the minimum amount of coins you have to pay to make x equal to 1?
Input
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
Output a single integer — the minimum amount of coins you have to pay to make x equal to 1.
Examples
inputCopy
9
2
3
1
outputCopy
6
inputCopy
5
5
2
20
outputCopy
8
inputCopy
19
3
4
2
outputCopy
12
Note
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.
题意
给一个数n,和k。x最开始和n相等,要求x变成1。
有如下两种操作
- 让x自减1,这个操作消耗A。
- 如果x可以整除k的话,让
x /= k
。这种操作消耗B。
求最少的花费,使得x变成1。
思路
我。。因为前几天写了道dp,然后思维惯性上dp了。。以至于学弟都写出来了我还没写出来。
其实贪心就好了嘛。
重复执行以下条件,直到x == 1
- 如果x < k,只能执行x - 1次第一种操作,然后答案加(x - 1) * A终止。
- 如果x不能被k整除,那肯定只能执行第一种操作,x % k次。也就是x -= x %k,然后答案加(x % k) * A。
- 如果x能被k整除,则判断从x到x / k那种操作花费更小,设
x / k = t;
,判断是(x - t) * A
和B
哪个小,如果是(x - t) * A
小的话,那就答案加上(x - t) * A
。如果是B小的话答案加上B
。最后x = t
。因为这一步操作不管怎么样x都是会到t的。
代码
// #pragma comment(linker, "/STACK:1024000000,1024000000")
#include <stdio.h>
#include <iostream>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <string>
#include <cstring>
#include <algorithm>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <ctime>
#include <vector>
#include <fstream>
#include <list>
#include <iomanip>
#include <numeric>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
#define ms(s) memset(s, 0, sizeof(s))
const int inf = 0x3f3f3f3f;
#define LOCAL
const int maxn = 1e6 + 7;
int main(int argc, char * argv[])
{
long long n, k, a, b;
while (cin >>n >> k >> a >> b){
if (k == 1){
cout << (n - 1) * a << endl;
}
else{
long long x = n;
long long ans = 0;
long long t;
while (x > 1){
if (x < k){
ans += (x - 1) * a;
break;
}
if (x % k != 0){
ans += (x % k) * a;
x -= x % k;
// if (x == 0){
// ans += (x % k - 1) * a;
// }
// else{
ans += (x % k) * a;
// }
}
else{
t = x / k;
if ((x - t) * a < b){
ans += (x - t) * a;
}
else{
ans += b;
}
x = t;
}
}
cout << ans << endl;
}
}
return 0;
}