Integer division - the interval dp (gravel merger)

This is not a number to a to divide, but to an integer bits divided

Title Description

How a positive integer N (N length <20) divided into M (M> 1) parts, so that the product of the maximum M portions. N, M input from the keyboard, and outputs the maximum one division manner.

Input Format

The first line of a positive integer T (T <= 10000), expressed T set of data.

The next two lines each line T positive integers N, M.

Output Format

For each test

The first line of maximum output.

The second line of the output division scheme, the sequence is divided into M number of N outputs, the number of opening between the two elements by spaces.

Sample

Sample input

1
199 2

Sample Output

171
19 9

这是递归思想,动态规划是正向的,而判断后是逆向的,输出时运用回溯,达到正向输出的目的
以下是代码
#include <the iostream> 
#include <cstdio> 
#include <CString>
 the using  namespace STD; 
unsigned Long  Long T, n-[ 21 is ], N2, N3 [ 21 is ] [ 21 is ], X, Son [ 1000 ] [ 1000 ], F [ 21 is ] [ 21 is ], m; // for the maximum, with an unsigned long integer 
String N1;
 int printf1 ( int A, int B) // output functions, backtracking 
{
     IF (B == 0 ) return  0 ; 
    printf1 (son [a] [b ], b-1);
    for(int i=son[a][b]+1;i<=a;i++)
        cout<<n[i];
    cout<<" ";
}
int main()
{
    cin>>t;
    for(int l=1;l<=t;l++)
    {
        memset(n,0,sizeof(n));
        memset(son,0,sizeof(son));
        cin>>n1>>m;
        n2=n1.length();
        for(int i=0;i<=n2;i++)
            for(int j=0;j<=n2;j++)
            {
                f[i][j]=0;
                //n3[i][j]=1;
            }    
        f[0][0]=1;
        for(int i=1;i<=n2;i++)
        {
            n[i]=n1[i-1]-'0';
            //cout<<n[i];
        }
        for(int i=1;i<=n2;i++)
        {
            x=n[i];
            for(int j=i;j<=n2;j++)
            {
                n3[i][j]=x;
                x*=10;
                x+=n[j+1];
                //cout<<n3[i][j]<<" "<<i<<" "<<j<<endl;
            }
        }
        for(int i=1;i<=n2;i++)
        {
            for(int j=1;j<=m&&j<=i;j++)
            {
                for(int k=1;k<=i;k++)
                {
                    if(f[i][j]<f[k-1][j-1]*n3[k][i])
                    {
                        f[i][j]=f[k-1][j-1]*n3[k][i];
                        //cout<<f[i][j];
                        son[i][j]=k-1;//记录分割点
                    }
                    
                }
            }
        }
        cout<<f[n2][m]<<endl;
        if(m==n2)//特判,防止输出紊乱
            for(int i=1;i<=n2;i++)
                cout<<n[i]<<" ";
        else printf1(n2,m);
        cout<<endl;
    }
}

 

 石子合并

Title Description

Playground around a circular stones piled placed N, Stone is to have order to merge into a pile. Each time only a predetermined selected adjacent stack 2 into a new pile and the new pile of stones number, remember that the combined score.

Test design an algorithm to calculate the N stones piled into a stack the maximum combined score.

Input Format

A first data line test positive integer N, 1≤N≤2000, N stones piled expressed. The second row has the number N, respectively, represent the number of each pile of stones.

Output Format

The output common line 1, the maximum score

Sample

Sample input

4
4 4 5 9

Sample Output

54
最终一堆一定是前一次合并后,剩下的两堆相加的最优解。

State transition equation
provided t [i, j] denotes the i-th stack from the stack to the sum of the j-number of stones.
Fmax (i, j) represents the i-heap of stones from the merger to the maximum score of the j-heap of stones
Fmin (i, j) represents the i-heap of stones from the combined minimum score of j-heap of stones (see the meaning of the questions not required)

 

附上代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,m[4001],m1[4001][4001],f[4001][4001],x,ma;
int main()
{
    cin>>n;
    for(int i=1;i<=n;i++)
    {
        cin>>m[i];
    }
    for(int i=1;i<=n;i++)
    {
        m[i+n]=m[i];
    }
    for(int i=1;i<=2*n-1;i++)
    {
        x=m[i];
        for(int j=i+1;j<=2*n-1;j++)
        {
            x+=m[j];
            m1[i][j]=x;
        }
    }
    for(int i=2*n-1;i>=1;i--)
    {
        for(int j=i;j<=2*n-1;j++)
        {
            f[i][j]=max(f[i+1][j],f[i][j-1])+m1[i][j];
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(ma<f[i][i+n-1])ma=f[i][i+n-1];
    }
    cout<<ma;
}

 




 

 

 

Guess you like

Origin www.cnblogs.com/fengwu2005/p/11274738.html