Codeforces Round #466 (Div. 2) B. Our Tanya is Crying Out Loud[将n变为1,有两种方式,求最小花费/贪心]

B. Our Tanya is Crying Out Loud
time limit per test
1 second
memory limit per test
256 megabytes
input
standard input
output
standard output

Right now she actually isn't. But she will be, if you don't solve this problem.c++

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: ide

  1. Subtract 1 from x. This operation costs you A coins.
  2. 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).this

The second line contains a single integer k (1 ≤ k ≤ 2·109).spa

The third line contains a single integer A (1 ≤ A ≤ 2·109).code

The fourth line contains a single integer B (1 ≤ B ≤ 2·109).orm

Output

Output a single integer — the minimum amount of coins you have to pay to make x equal to 1.blog

Examples
Input
Copy
9
2
3
1
Output
6
Input
Copy
5
5
2
20
Output
8
Input
Copy
19
3
4
2
Output
12
Note

In the first testcase, the optimal strategy is as follows:ci

  • 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.input

In the second test case the optimal strategy is to subtract 1 from x 4 times paying 8 coins in total.it

[题意]:将n变为1,有两种方式① n-1花费a , ② 若是n可以被k整除,n=n/k,花费b.求最小花费.

[分析]:很显然这是道贪心题,
一个很容易错的地方就是想着优先除二,而后在减一,
由于没有考虑二者的花费,若是b很大的话就错了,因此每次都要判断下,而后注意细节就好了

首先若是k==1,那么ans=(n-1)*a;

n%k!=0,只能执行操做1

n<k,只能执行操做1
n%k==0(n>=k) 的状况下比较n到达相同结果时两种操做的花费便可。

[代码]:

/* 题意:将n变为1,有两种方式①n-1花费a,②若是n可以被k整除,n=n/k,花费b,求最小花费 */
/* 很显然这是道贪心题, 一个很容易错的地方就是想着优先除二,而后在减一, 由于没有考虑二者的花费,若是b很大的话就错了,因此每次都要判断下,而后注意细节就好了 */ #include<bits/stdc++.h>
using namespace std; #define pb push_back
#define mem(a) memset(a,0,sizeof(a)) typedef long long ll; typedef pair<int,int> pii; const int maxn=150; const int inf=0x3f3f3f3f; int main() { ll x,n,k,a,b,ans; while(~scanf("%lld%lld%lld%lld",&n,&k,&a,&b)){ ans=0; if(k==1) return 0*printf("%lld\n",a*(n-1));  //注意特判k==1的状况,防止死循环
        while(n!=1){ //n没法整除k
            if(n%k!=0){    //不能整除只能减法(a),减到整除为止 
                ans+=a*(n%k); n-=(n%k); } if(n<k){       //此时只能减法(a),除法永远用不到,直接求解答案 
                ans+=a*(n-1); break; } //n能够整除k
            ans+=min(b,a*(n-n/k)); //减法(a)和除法(b)取最小花费 
            n/=k; //n能够整除k
 } printf("%lld\n",ans); } } /* n-n/k*k = n%k 获取距离n最近的k的倍数的方法是:n/k*k = n-n%k */
贪心
相关文章
相关标签/搜索