NYOJ 746 整数划分(四)

    整数划分(四)
时间限制:1000 ms  |  内存限制:65535 KB
难度:3

描述

           暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近遇到了一个难题,让他百思不得其解,他非常郁闷。。亲爱的你能帮帮他吗?

          问题是我们经常见到的整数划分,给出两个整数 n , m ,要求在 n 中加入m - 1 个乘号,将n分成m段,求出这m段的最大乘积

输入
    第一行是一个整数T,表示有T组测试数据
    接下来T行,每行有两个正整数 n,m ( 1<= n < 10^19, 0 < m <= n的位数);
输出
    输出每组测试样例结果为一个整数占一行
样例输入

    2
    111 2
    1111 2

样例输出

    11
    121


	#include<cstdio>  
    #include<cstdlib>  
    #include<cstring>  
    using namespace std;  
    long long t,dp[25][25];  
    long long num[25][25];  
    char str[25];  
    long long MAX(long long a,long long b)  
    {  
        return a>b?a:b;  
    }  
    int main()  
    {  
        int i,j,k,m;  
        scanf("%lld",&t);  
        while(t--)  
        {  
            scanf("%s%d",str,&m);  
            int l=strlen(str);m--;  
            memset(dp,0,sizeof(dp));  
            memset(num,0,sizeof(num));  
            for(i=0;i<l;++i)  
            {  
                num[i][i]=str[i]-'0';  
                for(j=i+1;j<l;++j)  
                {  
                    num[i][j]=num[i][j-1]*10+str[j]-'0';//求第i+1到第j+1位所组成的数   
                }  
            }  
            for(i=0;i<l;++i)  
            {  
                dp[i][0]=num[0][i];  
            }  
            for(i=1;i<=m;++i)//加入乘号数   
            {  
                for(j=i;j<l;++j)//前j位   
                {  
                    for(k=0;k<j;++k)  
                    {  
                        dp[j][i]=MAX(dp[j][i],dp[k][i-1]*num[k+1][j]); //先算出第一纵列的最大数乘,再进行比较出第二纵列的最大数乘 
                    }
                }  
            }  
            printf("%lld\n",dp[l-1][m]);  
        }  
        return 0;  
    } 
思路详解:如上 


你可能感兴趣的:(NYOJ 746 整数划分(四))