[Dynamic Planning Special 3: Minimum number of currency exchange for money

"Programmer Code Interview Guide --IT famous enterprises algorithms and data structures entitled optimal solution," Cheng Yun left the

Minimum number of currency exchange for money

[Title]
given array arr, all the values are positive in arr not repeated. Each value represents a face value of currency, each denomination currency can use any photos,
give a fixed integer aim, representatives looking to count the money, find the minimum number of currency composition of aim.

Examples
ARR = [5,2,3], AIM = 20 is
4 element may be composed of five - $ 20, other programs have to give change to use more money, it returns 4.

arr = [5,2,3], aim = 0
without any currency can be composed of $ 0, returns 0

arr = [3,5], aim = 2
is virtually impossible consisting of 2 million, the case where the money can not find open default -1.

 

 /// Method 1: Violence recursive solution

#include <algorithm> 
#include <the iostream> 
#include <Stack> 
#include <Vector> 
#include <Exception>
 the using  namespace STD; 

#define INT_MAX 1000 int GetMinNum ( int A, int B) 
{ return A> B? B: a; 
} int Process ( int * ARR, int length, int I, int REST); //// a recursive manner, the time complexity is high, is not recommended, but the idea here is to be understood recursive
 int minCoins1 ( int arr *, int



    


length, int AIM) { IF (ARR == nullptr a length || <= 0 || AIM <= 0 ) { return - . 1 ; } return Process (ARR, length, 0 , AIM); } // denomination currently considered is arr [i], the change needs money left rest // return -1 instructions free to use arr [i ... N-1] in the case of denomination, the change can not in any case rest // If the return not -1, representative of freedom using arr [i ... N-1] in the case of denomination, the minimum number of sheets required for the change rest int Process ( int * ARR, int length, int I, int rest) { // Base Case //The nominal value has no conceivable // If at this time the remaining money is 0, returns 0 // If at this time the remaining money is not 0, return -1 IF (I> = length) { IF (REST == 0 ) { cout << " ===================== " << endl; } return REST == 0 ? 0 : - 1 ; } // minimum number of sheets, the initial when -1, to find an effective solution because no int RES = - . 1 ; // sequentially try to use the current nominal value (arr [i]) 0 sheets, a, k sheets, but not more than REST for ( int K = 0; ARR k * [I] <= REST; k ++ ) { // use the k sheets aim [i], the remaining money is REST - k * ARR [I] // to get to the rest of the face value (ARR [N-I + .... 1. 1]) int Next = process (ARR, length, I + . 1 , REST - K * ARR [I]); // illustrate the subsequent process efficiently IF (= Next -! . 1 ) { RES = RES == - . 1 Next K +:? GetMinNum (RES, Next + K); } } COUT << " RES " << RES << endl; return RES; }

 

 

The recursive ideas into circulation. Currently not understand. . Recursive loop turn! ! !

Method 2: Auxiliary borrow dimensional array dp [N + 1] [aim + 1], by the circulation, from the bottom, layer by layer Solution.

void printDPArray(int* dp, int cols)
{
    for (int j = 0; j < cols; j++)
    {
        printf("%d,", (int)(*(dp + j)));
    }
    cout << endl;
}

int minCoin2(int* arr, int length, int aim)
{
    if (arr == nullptr || length <= 0 || aim < 0)
    {
        return -1;
    }
    int N = length;
    int** dp = new int*[N + 1];
    for (int i = 0; i < N+1; i++)
    {
        dp[i] = new int[aim + 1];
    }

    for (int i = 0; i < N + 1; i++)
    {
        for (int j = 0; j < aim + 1; j++)
        {
            DP [I] [J] = 0 ; 
        } 
    } 


    // set the value of the last row, except dp [N] [0] is 0 outside, the other is -1 
    DP [N] [ 0 ] = 0 ;
     for ( int COL = . 1 ; COL <= AIM; COL ++ ) 
    { 
        DP [N] [COL] = - . 1 ; 
    } 

    // up from the bottom of each row is calculated 
    for ( int I = N - . 1 ; I> = 0 ; I- - ) 
    { 
        // for each row from left to right 
        for ( int REST = 0; REST <= AIM; REST ++ ) 
        { 
            dp [i] [rest] = - . 1 ; // first set invalid value dp [i] [rest] of the initial 

            // The following if the value of the effective 
            IF (DP [I + . 1 ] [REST] = -! . 1 ) 
            { 
                DP [I] [REST] = DP [I + . 1 ] [REST]; // to set the following value 
            } 

            // If the position is not out of bounds and the left effective 
            IF (REST - ARR [I]> = 0 && DP [I] [REST - ARR [I]] = -! . 1 ) 
            { 
                // If the following value is invalid before 
                IF (DP [I] [REST] == - . 1 )
                {
                    DP [I] [REST] = DP [I] [REST - ARR [I]] + . 1 ; 
                } 
                the else 
                { 
                    // description following values are valid and the left, to the smallest 
                    dp [i] [rest] = GetMinNum ( DP [I] [REST], DP [I] [REST - ARR [I]] + . 1 ); 
                } 
            } 
        } 
    } 



    /// / print a two-dimensional array, somewhat unfamiliar. . . 
    for ( int I = 0 ; I <N + . 1 ; I ++ ) 
    { 
        printDPArray ( * (I + DP), AIM + . 1 ); 
    } 
    COUT << endl;
    cout << endl;

    cout << "printDPArray====================start" << endl;
    for (int i = 0; i < N + 1; i++)
    {
        printf("Row:%d.  ", i);
        for (int j = 0; j < aim + 1; j++)
        {
            printf("%d,", dp[i][j]);
        }
        cout << endl;
    }
    cout << "printDPArray====================end" << endl;

/*
    printDPArray == == == == == == == == == == start
    Row : 0.  0, -1, 1, 1, 2, 1, 2, 2, 2, 3, 2, 3, 3, 3, 4, 3, 4, 4, 4, 5, 4,
    Row : 1.  0, -1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7,
    Row : 2.  0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, 7, -1, 8, -1, 9, -1, 10,
    Row : 3.  0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
    printDPArray == == == == == == == == == == end
*/


    return dp[0][aim];
}

 

 

Then coins one by one scan, calculating for each denomination, the composition arr [i] ~ aim of the minimum number of currencies

The optimal solution is to rely on the back in front of the optimal solution, so you need to scan from left to right.

The number of the first row is arr [0] denomination coins sequentially composition 1 ~ aim, need

Method 3: a one-dimensional array of borrowing, is the length of the array aim + 1. This better understanding of some.

void PrintDPArr2(vector<int>& dp)
{
    for (vector<int>::iterator it1 = dp.begin(); it1 != dp.end(); ++it1)
    {
        cout << *it1<<",";
    }
    cout << endl;
}

void MiniCoin3(int* arr, int length, int aim)
{
    cout << "MiniCoin3======================" << endl;
    vector<int> dp(aim + . 1 , INT_MAX); 
    DP [ 0 ] = 0 ; 

    for ( int I = 0 ; I <length; ++ I) 
    { 
        for ( int J = ARR [I]; J <= AIM; ++ J) 
        { 
            IF ( ! DP [J - ARR [I]] = INT_MAX) 
            { 
                DP [J] = min (DP [J], DP [J - ARR [I]] + . 1 ); 
            } 
        } 
        PrintDPArr2 (DP); //// here is a temporary result of each print line, to facilitate post appreciated 
    } 

    IF (DP [AIM] == INT_MAX) COUT << " -1 " << endl;
    else  cout << "dp[aim] "<<dp[aim] << endl;

    /* aim=6,arr=[2,1,3]
    0,1000,1,1000,2,1000,3,
    0,1,1,2,2,3,3,
    0,1,1,1,2,2,2,
    dp[aim] 2    
    */
}

 

 

// ==================== test ================= 
void test1 () 
{ 
    int arrCoin1 [ . 3 ] = { 2 , . 1 , . 3 };
     int arrCoin2 [] = { . 1 , 2 , . 3 , . 4 , . 5 , . 6 , . 7 , . 8 , . 9 , 10 , 60 , 62 is , 100 , 101 , 102 , 103 , 104 , 105, 106, 107, 108, 109, 110, 112, 113, 114, 115, 116, 117 };
    //int arrCoin2[] = { 1,3,5,6 };

    //cout << "Test1================" << endl;
    //cout << "expected:4. " << minCoin2(arrCoin1, sizeof(arrCoin1) / sizeof(int), 6) << endl;;
    
    MiniCoin3(arrCoin1, sizeof(arrCoin1) / sizeof(int), 6);
    //MiniCoin3(arrCoin2, sizeof(arrCoin2) / sizeof(int), 122);

    
    //cout << "expected:2. " << minCoins1(arrCoin2, sizeof(arrCoin2) / sizeof(int), 122) << endl;;
}




int main()
{
    test1();

    cout << endl;
    system("pause");
    return 0;
}

 

Guess you like

Origin www.cnblogs.com/music-liang/p/12059230.html