NOIP2000TG T2 product of the maximum

Topic Link

 

Meaning of the questions:

 The $ N (6 <= N <= 40) bit digital $, with $ K (1 <= K <= 6) $ th multiplication spaced, seeking the maximum product.

 

Program 1 (0pt):

See Split / Merge, consider the range of DP, think about, because the number range is limited, can not set the interval DP fucks.

Because multiplication is associative, considered "first touch $ I $ bit" and "$ j in place the first one after this multiplication $ a" two dimensions as the DP, the maximum recording, set $ f_ {i , j} $.

First, as strings of the given number set $ A $, whichever part of the function is $ cut (a, l, r) $, found from the beginning to take high and low is the same, for simplicity, just as high precision and at the lowest position for the first $ 1 $ bit.

When each generated initial value with a first multiplication, each time from the state $ j-1 $'s.

At the same time, it makes sense because you can only transfer from the calculated state unknowable and strange error to avoid doing high-precision multiplication time there, so consider maintaining access this value in the realization of the DP, to $ v $.

Consider the median $ p $ satisfying the search for a node

① $ p> = j-1 $, because here to place the first $ j-1 $ th multiplication, at least a first position $ j-1 $

② $ p <i $, from front to back transfer

③ $ f_ {p, j-1} must be accessed $

So we have

$$f_{i,j}=\mathop{max}\limits_{p=j-1}^{i-1}\{([v_{p,j-1}]*f_{p,j-1}*cut(a,p+1,i)\}$$

After running $ f_ {i} $, apparently $ f_ {i, k} $ is the answer candidate.

However, there is a problem, is read. In such hybrid digital and string input can easily be explosive. The first time submitted because of burst read into the square. Good embarrassed ah.

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=40;
const int M=6;

struct num{
    int s[N+3],l;
    
    num(int x){
        memset(s,0,sizeof s);
        
        if(x==0){
            l=1;
            return ;
            
        }
        
        l=0;
        while(x>0){
            s[++l]=x%10;
            x/=10;
            
        }
        
    }
    
    num(){}
    
    int operator[](int i){
        return s[i];
        
    }
    
};

void prt(num a){
    for(int i=a.l;i>=1;i--)
        putchar(a[i]+'0');
    
}

num operator*(num a,num b){
    num c=num(0);
    
    for(int i=1;i<=a.l;i++)
        for(int j=1;j<=b.l;j++)
            c.s[i+j-1]+=a[i]*b[j];
    
    c.l=a.l+b.l+1;
    for(int i=1;i<c.l;i++){
        c.s[i+1]+=c[i]/10;
        c.s[i]%=10;
        
    }
    while(c[c.l]==0)
        c.l--;
        
    return c;
    
}

bool operator<(num a,num b){
    if(a.l!=b.l)
        return a.l<b.l;
    
    for(int i=a.l;i>=1;i--)
        if(a[i]!=b[i])
            return a[i]<b[i];
    return false;
    
}

num max(num a,num b){
    if(a<b)
        return b;
    return a;
    
}

num cut(num a,int l,int r){
    num b(0);    b.l=r-l+1;
    for(int i=1;i<=b.l;i++)
        b.s[i]=a[l+i-1];
    return b;
    
}

    num a;
    int n,k;
    num f[N+3][M+3],ans[N+3];
    bool v[N+3][M+3];
    

int main(){
    scanf("%d%d",&n,&k);getchar();
    char ch;    a.l=n;
    for(int i=n;i>=1;i--){
        ch=getchar();
        a.s[i]=ch-'0';
        
    }
    
    memset(v,0,sizeof 0);
    for(int i=1;i<n;i++){            
        f[i][1]=cut(a,1,i);
        v[i][1]=true;
        
        for(int j=2;j<=k;j++)        
            for(int p=j-1;p<i;p++)    
            if(v[p][j-1]){
                v[i][j]=1;
                f[i][j]=max(f[i][j]
                    ,f[p][j-1]*cut(a,p+1,i));
                
            }
            
        if(v[i][k])    
            ans[i]=f[i][k]*cut(a,i+1,n);
    
    num maxa(0);
    for(int i=1;i<n;i++)
    if(v[i][k])
        maxa=max(maxa,ans[i]);
    prt(maxa);
    
    return 0;
    
}

 

 

 

Program 2 (100pt):

Thought a moment, it should be $ scanf $ and $ getchar $ mixed on the same line, I do not know where to go due to the carriage. In fact, I have not too thoroughly understand one of the mechanisms.

Enter consider the close up mode sequence.

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
typedef long long LL;
const int N=40;
const int M=6;

struct num{
    int s[N+3],l;
    
    num(int x){
        memset(s,0,sizeof s);
        
        if(x==0){
            l=1;
            return ;
            
        }
        
        l=0;
        while(x>0){
            s[++l]=x%10;
            x/=10;
            
        }
        
    }
    
    num(){}
    
    int operator[](int i){
        return s[i];
        
    }
    
};

void prt(num a){
    for(int i=a.l;i>=1;i--)
        putchar(a[i]+'0');
    
}

num operator*(num a,num b){
    num c=num(0);
    
    for(int i=1;i<=a.l;i++)
        for(int j=1;j<=b.l;j++)
            c.s[i+j-1]+=a[i]*b[j];
    
    c.l=a.l+b.l+1;
    for(int i=1;i<c.l;i++){
        c.s[i+1]+=c[i]/10;
        c.s[i]%=10;
        
    }
    while(c[c.l]==0)
        c.l--;
        
    return c;
    
}

bool operator<(num a,num b){
    if(a.l!=b.l)
        return a.l<b.l;
    
    for(int i=a.l;i>=1;i--)
        if(a[i]!=b[i])
            return a[i]<b[i];
    return false;
    
}

num max(num a,num b){
    if(a<b)
        return b;
    return a;
    
}

num cut(num a,int l,int r){
    num b(0);    b.l=r-l+1;
    for(int i=1;i<=b.l;i++)
        b.s[i]=a[l+i-1];
    return b;
    
}

    num a;
    int n,k;
    num f[N+3][M+3],ans[N+3];
    bool v[N+3][M+3];
    

int main(){
    scanf("%d%d\r",&n,&k);
    char ch;    a.l=n;
    for(int i=n;i>=1;i--){
        ch=getchar();
        a.s[i]=ch-'0';
        
    }
    
    memset(v,0,sizeof 0);
    for(int i=1;i<n;i++){                
        f[i][1]=cut(a,1,i);
        v[i][1]=true;
        
        for(int j=2;j<=k;j++)                
            for(int p=j-1;p<i;p++)                
            if(v[p][j-1]){
                v[i][j]=1;
                f[i][j]=max(f[i][j]
                    ,f[p][j-1]*cut(a,p+1,i));
                
            }
            
        if(v[i][k])                        
            ans[i]=f[i][k]*cut(a,i+1,n);        
    
    num maxa(0);
    for(int i=1;i<n;i++)
    if(v[i][k])
        maxa=max(maxa,ans[i]);
    prt(maxa);
    
    return 0;
    
}

 

 

summary:

Terrible string engage in law ......

 

Guess you like

Origin www.cnblogs.com/Hansue/p/10960815.html