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 */
貪心
相關文章
相關標籤/搜索