Dynamic programming algorithm machine side

Posted by adunphy on Wed, 01 Dec 2021 00:04:27 +0100

A - high number Umaru series (9) - Husky

Description
Because the meow star people raised by Gao Shuju are too arrogant, they have to eat fresh cat food every day and often bully Gao Shuju, so Gao Shuju decides to buy some huskies to taste fresh. On this day, Gao Shuju came to the second-hand dog market to buy husky. Gao Shuju read all husky, wrote down the price of each husky, and gave each of them a sprouting value according to their favor. Gao Shu now has x yuan in her hand. She wants to get as much sprouting value as possible by buying several haskis. Now, given the price and MOE value of X and N husky in the hands of the high number giant, how much MOE value can the high number giant obtain at most

Input
Multiple sets of inputs.

For each group of inputs, the first line has two integers N, X (1 < = N < = 100, 1 < = x < = 1000), representing the number of husky and the high number of huge money, respectively

In the next N lines, there are two integers PI and Mi (1 < = Pi, Mi < = 100) in each line, representing the price and sprout value of article i husky respectively

Output
For each group of data, an integer is output to represent the maximum sprout value that can be obtained by the high number giant, and each group of output accounts for one line

Sample
Input
2 100
50 20
60 40
3 100
20 55
20 35
90 95
1 10
20 50
Output
40
95
0

#include<bits/stdc++.h>
using namespace std;
int max(int a,int b)//Comparison function;
{
    return a>b?a:b;
}
int main()
{
    int n,x,p,m;
    while(cin>>n>>x)
    {
        int dp[110][1009]= {0}; ///dp array initialization
        for(int i=1; i<=n; i++)
        {
            cin>>p>>m;
            for(int j=1; j<=x; j++) //j traverse from 1 to the given amount
            {
                dp[i][j]=(i==1?0:dp[i-1][j]);//Inherit the data in the previous row and migrate the data
                if(j>=p)
                {
                    dp[i][j]=max(dp[i-1][j],dp[i-1][j-p]+m);
                }
            }
        }
        cout<<dp[n][x]<<endl;
    }
    return 0;
}

B - Minimum coin problem

Description
There are n coins with different denominations, and the denominations of each coin are stored in the array T[1:n]. Now I want to change with these coins. The number of coins of various denominations that can be used is stored in the array Coins[1:n].
For any number of money 0 ≤ m ≤ 20001, a method of changing m with the least coin is designed.
For a given 1 ≤ n ≤ 10, the coin denomination array T, the number of Coins of various denominations that can be used, and the number of money m, 0 ≤ m ≤ 20001, calculate the minimum number of Coins for change M.
Input
Only one integer in the first row of the input data gives the value of n, and there are two numbers in each row from the second row, namely T[j] and Coins[j]. The last line is the change m.
Output
The output data has only one integer, indicating the minimum number of coins calculated. Output - 1 when the problem has no solution.
Sample
Input
3
1 3
2 3
5 3
18
Output
5

#include<bits/stdc++.h>
#define INF 9999
using namespace std;
struct Coins  //It is convenient to use the structure
{
    int t;
    int c;
} coins[20];
int min(int a,int b)
{
    return a>b?b:a;
}
int main()
{
    int n,dp[30000],m;
    cin>>n;
    for(int i=1; i<=n; i++)
    {
        cin>>coins[i].t>>coins[i].c;
    }
    cin>>m;
    for(int i=1; i<=m; i++)  //For the initialization of arrays other than 0 and - 1, it's best not to use memset, which is sometimes garbled. The specific reason is not clear. Memset is not recommended. The amount of data in this problem is small. Just be honest and practical for loop traversal
    {
        dp[i]=INF;
    }
    for(int i=1; i<=n; i++)
    {
        for(int j=1; j<=coins[i].c; j++)
        {
            for(int k=m; k>=coins[i].t; k--)
            {
                dp[k]=min(dp[k],dp[k-coins[i].t]+1);
            }
        }
    }
    if(dp[m]==INF)
        cout<<"-1"<<endl;
    else
        cout<<dp[m]<<endl;
}

C - Digital triangle problem

Description
Given a number triangle composed of n lines of numbers, as shown in the figure below. Try to design an algorithm to calculate a path from the top to the bottom of the triangle to maximize the sum of the numbers that the path passes through.

For a given digital triangle composed of n rows of numbers, calculate the maximum value of the sum of numbers passing through the path from the top to the bottom of the triangle.
Input
The first row of input data is the number of rows n of digital triangle, 1 ≤ n ≤ 100. The next n rows are the numbers in each row of the number triangle. All numbers are between 0... 99.
Output
The output data has only one integer, representing the calculated maximum value.
Sample
Input
5
7
3 8
8 1 0
2 7 4 4
4 5 2 6 5
Output
30

#include<bits/stdc++.h>
using  namespace std;

int main()
{
    int n;
    int a[101][101];
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=i;j++)
        {
            cin>>a[i][j];
        }
    }
    int b[101][101];
    for(int i=1;i<=n;i++)
    {
        b[n][i]=a[n][i];
    }
    for(int i=n-1;i>=1;i--)
    {
        for(int j=1;j<=i;j++)
        {
             b[i][j]=a[i][j]+max(b[i+1][j],b[i+1][j+1]);
        }
    }
    cout<<b[1][1]<<endl;
    return 0;
}

D - stone merging problem

Description
There are n heaps of stones around a circular playground. Now we need to merge the stones into a pile in order. It is stipulated that only two adjacent piles of stones can be selected each time to combine into a new pile, and the number of new piles of stones shall be recorded as the score of the combination. Try to design an algorithm to calculate the minimum score and maximum score of merging n piles of stones into one pile.
For a given n pile of stones, calculate the minimum score and maximum score combined into a pile.
Input
The first line of the input data is a positive integer n, 1 ≤ n ≤ 100, indicating that there are n stones. The second row has n numbers, which respectively represent the number of stones in each pile.
Output
There are two rows of output data. The number in the first row is the minimum score and the number in the second row is the maximum score.
Sample
Input
4
4 4 5 9
Output
43
54

#include <iostream>
#include <algorithm>
#include <memory.h>
#define inf 0x3f3f3f3f
using namespace std;
int main()
{
    int n,i,j,k,a[202],dp[202][202],dpm[202][202];
    cin>>n;
    memset(dp,0,sizeof(dp));
    memset(dpm,0,sizeof(dpm));
    for(i=1; i<=n; i++)
    {
        cin>>a[i];
        a[i+n]=a[i];
    }
    int sum[202];
    sum[0]=0;
    for(i=1; i<=2*n; i++)
    {
        sum[i]=sum[i-1]+a[i];
    }
    for(i=2*n-1; i>=1; i--)
    {
        for(j=i+1; j<i+n&&j<=2*n; j++)
        {
            dpm[i][j]=inf;
            for(k=i; k<j; k++)
            {
                dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
                dpm[i][j]=min(dpm[i][j],dpm[i][k]+dpm[k+1][j]+sum[j]-sum[i-1]);
            }
        }
    }
    int maxx=-1,minn=inf;
    for(i=1; i<=n; i++) //The values of n intervals are compared
    {
        maxx=max(maxx,dp[i][i+n-1]);
        minn=min(minn,dpm[i][i+n-1]);
    }
    cout<<minn<<endl;
    cout<<maxx<<endl;
    return 0;
}

E - longest common subsequence problem

Description
Given two sequences X={x1,x2,..., xm} and Y={y1,y2,..., yn}, find the longest common subsequence of X and y.

Input
There are multiple groups of input data, each group has two lines, and each line has a string with a length of no more than 500 (the input is all uppercase English letters (A,Z)), representing the sequence X and Y.

Output
Each group outputs one line, indicating the length of the longest common subsequence obtained. If there is no common subsequence, 0 is output.

Sample
Input
ABCBDAB
BDCABA
Output
4

#include<bits/stdc++.h>
using namespace std;
///Longest common subsequence problem
int main()
{
    int m,n;
    char s1[501],s2[501];
    while(cin>>s1>>s2)
    {
        m=strlen(s1);
        n=strlen(s2);
        int c[m+1][n+1];
        for(int i=0; i<=m; i++)
            c[i][0]=0;
        for(int i=0; i<=n; i++)
            c[0][i]=0;
        for(int i=1; i<=m; i++)
            for(int j=1; j<=n; j++)///Recurrence formula
            {
                if(s1[i-1]==s2[j-1])
                    c[i][j]=c[i-1][j-1]+1;
                else
                    c[i][j]=max(c[i-1][j],c[i][j-1]);
            }
        cout<<c[m][n]<<endl;
    }
}

Topics: Algorithm Dynamic Programming