940B Our Tanya is Crying Out Loud

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.

You are given integers nkA and B. There is a number x, which is initially equal to n. You are allowed to perform two types of operations:

  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 Bcoins.
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
input
Copy
9
2
3
1
output
Copy
6
input
Copy
5
5
2
20
output
Copy
8
input
Copy
19
3
4
2
output
Copy
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,A,B,你要把n经过两种操作变成1,一种是操作是每次减1,需要花费A个硬币,如果当前n是K的倍数,n也可以除以k,花费B个硬币。输出最少的花费,让n变成1.


题解:贪心    最开始我是贪心模拟的,如果n是k的倍数,就比较除以k的花费,和n一个一个减1到n/k一样大小的花费,取花费较小的,不是k的倍数,就一个一个减,思路没错,但是会超时,因为不是k的倍数,数据很大的情况下,一个一个减会超时滴,然后就优化嘛,我们需要比较花费的时候是n是k的倍数的时候,所以不是倍数的时候,就不要一个一个减,一次性减到n是k的倍数。n-=n%k。时间复杂度大大降低,第四组数据最开始的模拟要话14秒,然后优化后第四组数据0秒。

#include<bits/stdc++.h>
using namespace std;
int main()
{
    long long n,k,a,b,ans=0;
    cin>>n>>k>>a>>b;
//    double s=clock();
    while(n>1)
    {
        ans+=n%k*a;
        n-=n%k;
        if((n-n/k)*a<b)
              ans+=(n-1)*a,n=1;
        else ans+=b,n=n/k;
    }
//    double t=clock();
//    cout<<(t-s)/1000<<"毫秒"<<endl;
    cout<<ans<<endl;
    return 0;
}


猜你喜欢

转载自blog.csdn.net/memory_qianxiao/article/details/80085548