整数划分

Posted lightyachoo

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了整数划分相关的知识,希望对你有一定的参考价值。

题目描述

如何把一个正整数N(N长度<20)划分为M(M>=1)个部分,使这M个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。

输入格式

第一行一个正整数T(T<=10000),表示有T组数据。

接下来T行每行两个正整数N,M。

输出格式

对于每组数据

第一行输出最大值。

第二行输出划分方案,将N按顺序分成M个数输出,两个数之间用空格格开。

样例

样例输入

1
199 2

样例输出

171
19 9
#include<bits/stdc++.h>
using namespace std;
long long t,n[21],n2;
long long n3[21][21],x;
long long son[1000][1000],f[21][21],m;
string n1;
int printf1(int a,int b){
    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;
        }
        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];
            }
        }
        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];
                        son[i][j]=k-1;
                    } 
                }
            }
        }
        printf("%lld
",f[n2][m]);
        if(m==n2)
            for(int i=1;i<=n2;i++)
                cout<<n[i]<<" ";
        else printf1(n2,m);
        cout<<endl;
    }
}

 

以上是关于整数划分的主要内容,如果未能解决你的问题,请参考以下文章

动态规划整数划分及其变种

Java 求解划分字母区间

763. 划分字母区间

Leetcode 763 划分字母区间

贪心算法:划分字母区间

763.划分字母区间