Dynamic Programming 1- king and gold

reference

https://juejin.im/post/5a29d52cf265da43333e4da7

One country found five gold, different every goldmine of gold reserves, the number of workers involved in mining needs are different. The total number of workers involved in mining is 10 people. Each goldmine either all dig, dig or not, can not send half of them gold digging half. How to allocate the required workers to dig up gold.

The first gold 500 gold mines, required 5; second seat gold 200 gold, requires 3; third gold 300 gold mines, required 4; fourth gold 350 gold mine, requires 3 people; fifth gold mine gold 400, take 5 people.

Most began to think that the proportion of gold in the gold content of each operator and the needs of workers, that is, each person's amount of gold to be tapped, according to descending, sort, select the largest. But now we have a fixed number, not a limited number of people. It is possible to meet the first, leading to the back of people can not dig a mining or less offset the front edge. So here it is to be calculated in each case, the optimal solution.

The problem, according to decompose, seeking a fifth gold maximum value, is currently seeking to dig gold and the rest of the first four people to dig and do not dig gold current gold and everyone dug in front of four of the largest gold mine value. f (5) = max (f (4, n), f (4, np) + G (5)). Some people may say that since the first four can add a fifth, then certainly add ah. However, the maximum value of the first four gold, four is not necessarily all dig, to combine the fifth gold mine, it is possible to use fewer workers, some of the first four gold did not dig. So seeking four gold mines, on request three gold, it has been to find a gold mine.

The first method is exhaustive, all the listed cases, and one judgment, so the worst efficiency.

The second method is the above, according to the formula, to find layers, such as calculating n = 5, calculates n = 4, until n = 1, then returns. However, this calculation is very troublesome, because n each calculation, there is a case that the n-gold mine included, is to send people to dig a gold mine of n, then the total number of changes took place, it means to re-iterate the previous calculation.

int gold[] = { 500,200,300,350,400 };
int workers[] = { 5,3,4,3,5 };
void dgold(bool* diggold, int index, int pnum)
{
    if (index == 0)
    {
        if (pnum >= workers[0])
        {
            diggold[0] = true;
        }
    }
    else
    {
        bool tmp[5] = { false };
        memcpy(tmp, diggold, 5 * sizeof(bool));
        tmp[index] = false;
        dgold(tmp, index - 1, pnum);
        bool tmp1[5] = { false };
        memcpy(tmp1, diggold, 5 * sizeof(bool));
        if (pnum >= workers[index])
        {
            tmp1[index] = true;
        }
        dgold(tmp1, index - 1, pnum - workers[index]);
        int tmpgold = 0;
        for (int i = 0; i <= index; i++)
        {
            if (tmp[i])
            {
                tmpgold += gold[i];
            }
        }
        int tmpgold1 = 0;
        for (int i = 0; i <= index; i++)
        {
            if (tmp1[i])
            {
                tmpgold1 += gold[i];
            }
        }
        if (tmpgold > tmpgold1)
        {
            memcpy(diggold, tmp, 5 * sizeof(bool));
        }
        else
        {
            memcpy(diggold, tmp1, 5 * sizeof(bool));
        }
    }
}
int main ()
{
    bool diggold[5] = { false };
    dgold(diggold, 4, 10);
    char inchar;
    cin >> inchar;
}

This is the recursive traversal. We want to take the case of the first n gold mine, then there are two, a gold mining is the n seat, the other is not the first n gold mine exploitation. Then sequentially and recursively calculated two maxima. Recursive export is the first gold mine.

This question is that there are other solutions? Yes, that is dynamic programming 2- longest common subsequence of speaking, we look at the table

 

With the longest common subsequence feel as derived from the above equation, f (5) = max (f (4, n), f (4, np) + G (5)), found that the n-th request goldmine the optimal solution is equivalent to the current gold included, then remove the necessary number of this gold mine, then look for gold before n-1, the number is 10-p (p is the current gold human needs) data corresponding to their previous data (n-th gold mines are not counted) Max. Such previous data obtained can also be used. code show as below

int gold[] = { 500,200,300,350,400 };
int workers[] = { 5,3,4,3,5 };
int main()
{
    //i is gold j is people
    auto optgold = new int[10 * 5]();
    int maxgold = 0;
    int maxi = 0;
    int maxj = 0;
    for (int j = 0; j < 10; j++)
    {
        for (int i = 0; i < 5; i++)
        {
            if (j + 1 < workers[i])
            {
                if (i - 1 < 0)
                {
                    *(optgold + j * 5 + i) = 0;
                }
                else
                {
                    *(optgold + j * 5 + i) = *(optgold + j * 5 + i - 1);
                }
            }
            else
            {
                int pre = 0 ; // this is not gold mining, the maximum 
                IF (I - . 1 > = 0 )
                {
                    pre = *(optgold + j * 5 + i - 1);
                }
                int Mnow = Gold [I]; // current gold mining, the maximum 
                IF (I - . 1 > = 0 && J - Workers [I]> = 0 )
                {
                    mnow = mnow + *(optgold + (j - workers[i]) * 5 + i - 1);
                }
                if (pre > mnow)
                {
                    *(optgold + j * 5 + i) = pre;
                }
                else
                {
                    *(optgold + j * 5 + i) = mnow;
                }
            }
            if (*(optgold + j * 5 + i) > maxgold)
            {
                maxgold = *(optgold + j * 5 + i);
                max = i;
                maxj = j;
            }
        }
    }
    maxj++;
    while (maxj > 0)
    {
        for (int i = 0; i <= maxi; i++)
        {
            if (*(optgold + (maxj - 1) * 5 + i) == maxgold)
            {
                maxi = i;
                break;
            }
        }
        cout << "gold " << gold[maxi] << " worker " << workers[maxi] << " gold " << maxi + 1 << endl;
        maxj = maxj - workers[maxi];
        maxgold = maxgold - gold[maxi];
        maxi--;
        
    }
    char swell;
    cin >> inchar;
}

Problems encountered, one, dug in the calculation of the current mine when the mine forget the amount of current added to the list; Second, because the index j and a number of poor, leading to the final traverse output at an inconvenient time.

Guess you like

Origin www.cnblogs.com/studywithallofyou/p/12121507.html