------------只要够努力,人生最坏的结局不过是大器晚成!!!

/*                                            整数划分(四)
时间限制: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

来源
    经典题目
*/
//思路:区间dp,设dp[i][j] 表示在区间[0, i]之中,插入j个乘号可以得到的最大数
//设a[i][j]为区间[i,j]所形成的数所以 dp[i][j] = max(dp[k][j-1] * a[k + 1][i])
 
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
typedef long long ll;
ll dp[25][25];
ll a[25][25];
char b[25];

ll fun(int i, int j){   //注意递归的条件
    if(dp[i][j] != 0)
        return dp[i][j];
    if(i < j)   //可以等于
        return 0;
    if(i == 0 || j == 0){
        return dp[i][j] = a[0][i];
    }
    for(int k = 0; k <= i - 1; k++){
        dp[i][j] = max(fun(k, j - 1)*a[k+1][i], dp[i][j]);
//        cout << "k : " << k << " " << "i :" << i << " a: " << a[k+1][i] << " " << dp[i][j] << endl;
    }
    return dp[i][j];
}

int main(){
    int n;
    cin >> n;
    while(n--){
        memset(dp, 0, sizeof(dp));
        memset(b, 0, sizeof(b));
        memset(a, 0, sizeof(a));
        ll s = 0, m = 0;
//        while(~scanf("%c", &b[s++]))
//            ;    
        scanf("%s", b);    
        scanf("%lld", &m);
        s = strlen(b);
        if(m > s){
            cout << 0 << endl;
            continue;
        }
        for(int i = 0; i < s; i++){
            a[i][i] = b[i] - '0';
            for(int j = i + 1; j < s; j++){
                a[i][j] = a[i][j - 1] * 10 + b[j] - '0';                
            }
        }
//递归:
//        printf("%lld\n", fun(s - 1, m - 1));

//递推:
        for(int i = 0; i < s; i++)
            dp[i][0] = a[0][i];
        for(int i = 1; i < s; i++){
            for(int j = 1; j <= m - 1; j++){
                for(int k = 0; k < i; k++)
                    dp[i][j] = max(dp[i][j], dp[k][j - 1]*a[k+1][i]);                
            }
        }
        cout << dp[s-1][m-1] << endl;
/*        
        for(int i = 0; i < s; i++){
            for(int j = 0; j < s; j++)
                cout << a[i][j] << " ";
            cout << endl;        
        }
*/    
    }
    return 0;
}

posted on 2017-08-25 20:57  ystraw  阅读(533)  评论(0编辑  收藏  举报

不经一番切孤寒,怎得梅花扑鼻香