Luogu - P1018 product maximum problem solution

Original text: https://www.luogu.org/problemnew/solution/P1018?page=7

 

Title: P1018 [maximum product]

 

Preface:

  • In theory, the positive solution of this problem is DP, but it is not difficult to use violence because of too much private data

Overall thinking:

  1. A b array is used to mark whether each bit is divided (1-bit division, 0 is connection).
  2. The next permutation in STL is used to find out various permutations of b (i.e. violent enumeration of each case).
  3. Because of the large scale of the data, we need to use high precision to calculate the final result of each segmentation and find out the maximum.

 

Next < permutation function:

  • That is, STL Full Permutation Function, the array must be in ascending order, otherwise it will not be able to find all the permutations (which is related to the way it generates group permutations). Next ﹐ permutation is normal as sort, with two parameters, namely, the first address and the last address of the array, and returns a bool quantity, that is, whether the next full permutation can be found, if possible, returns true, and changes the specified array to the next row Column mode, for example, the next arrangement mode of 1 23 is 1 32.

 

Upper Code:

#include<algorithm> //Use next_permutation Header file to call
#include<cstdio>  //c Language read in output
#include<cstring>  //High precision string processing requires

using namespace std;

struct BigN{  //High precision (i.e. large integer) operation
    int num[1001]={0},len;
    BigN(char s[])  //Constructor, which assigns a value to a newly defined large integer
    {
        len=strlen(s);
        for(int i=len-1;i>=0;i--)
            num[i]=s[len-i-1]-'0';
    }
    void clean()  //Used for clearing
    {
        memset(num,0,sizeof(num));
    }
    void f(int n)  //Press an ordinary integer to the beginning of a large integer, which will be used to split each bit later
    {
        for(int i=len;i>0;i--)
            num[i]=num[i-1];
        len++;
        num[0]=n;
    }
    void cheng(BigN n)//High precision multiplication, this is just more explanation, you can go to P1303 Learn more
    {
        BigN c("0");
        int s=0,g=0;
        for(int i=0;i<=len;i++)
            for(int j=0;j<=n.len;j++)
            {
                int w=i+j;
                s=num[i]*n.num[j];
                c.num[w]+=s%10;
                c.num[w+1]+=s/10+c.num[w]/10;
                c.num[w]%=10;
            }
        c.len=len+n.len;
        while(c.num[c.len]==0&&c.len>=0)c.len--;
        fz(c);
    }
    void fz(BigN n) //Assign a large integer to an exception, which is equivalent to'='
    {
        len=n.len;
        for(int i=0;i<=n.len;i++)
            num[i]=n.num[i];
    }
    bool bj(BigN n)  //Determine the size of two large integers to find the maximum result
    {
        if(len>n.len)
            return 1;
        else if(len<n.len)
            return 0;
        else
        {
            for(int i=len;i>=0;i--)
                if(num[i]<n.num[i])
                    return 0;
                else if(num[i]>n.num[i])
                    return 1;
            return -1;
        }
    }
    void out() //output
    {
        for(int i=len;i>=0;i--)
            printf("%d",num[i]);
    }
};

int n,k,sum[55],b[55],i,j; //General definition, no more explanation
BigN mmax("0");

int main()
{
    char s[101];  //s Used to read in a large integer
    scanf("%d%d%s",&n,&k,&s);
    for(i=0;i<strlen(s);i++)  //stay sum Original number of backup copies in
        sum[i]=s[i]-'0';
    for(i=n-2;i>=(n-k)-1;i--)  //take b After in array k Number 1,Because use next_permutation You need to raise the array, or you may not be able to find all the permutations
        b[i]=1;
    do{
        BigN temp("0"),all("1");//temp It is used to store each divided section, all Used to calculate the results for each arrangement
        i=0;
        while(i<n)//Division
        {
            if(i!=0)
                if(b[i-1]==1)//If b[i-1]If it is 1, then you need to add a multiplier sign to this digit, that is, to divide the original number
                    all.cheng(temp),temp.clean();//Multiply the total by each bit after segmentation,And will temp Empty to store next section.
            temp.f(sum[i]),i++; //Press the next bit of the original number to temp Foremost
        }
        all.cheng(temp);//Because temp Not yet. all Just exit the loop, so multiply again
        if(mmax.bj(all)==0)//If the result of this sort of arrangement is greater than the previous maximum result, refresh the maximum result
            mmax.fz(all);
    }while(next_permutation(b,b+n-1));//call next_permutation
    mmax.out();//output
    return 0;
}

Tags: C++ C

Posted on Sun, 10 Nov 2019 10:42:31 -0500 by NoDoze