ACM 整数划分(四)

 

整数划分(四)

时间限制: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


使用动态规划的思想,思考了整整一下午,没想到最后做出了5层循环的动态规划。好在题目AC了,后又看网上的答案,使用的是DP区间动态规划算法,今天就不去研究了,有些累。下面是我的算法

#include <string>
#include <sstream>
#include <iostream>
#include <string.h>
#include <stdio.h>
using namespace std;

#define NUM 20

long long atoll(const char* p)
{
    stringstream strValue;
    strValue << p;
    long long value;
    strValue >> value;
    return value;
}


int main()
{
    int count;
    scanf("%d", &count);
    while(count--)
    {
        int i,j,k,l,m,n;
        long long mm[NUM][NUM][NUM];
        char num[NUM];
        char temp[NUM];
        scanf("%s", num);
        n = strlen(num);
        scanf("%d", &m);
        for(k = 0; k < m; k++)
        {
            for(i = 0; i < n; i++)
            {
                for(j = i + k; j < n; j++)
                {
                    if(k == 0)
                    {
                        strncpy(temp, num+i, j-i+1);
                        temp[j-i+1] = '\0';
                        mm[i][j][k] = atoll(temp);
                    }
                    else
                    {
                        long long res = -1;
                        for(l = 0; l < j-i; l++)
                        {
                            int o, k1=0, k2=0;
                            for(o = 0; o < l+1 && o < k; o++)
                            {
                                k1 = o;
                                k2 = k - 1 - k1;
                                long long tRes = mm[i][i+l][k1] * mm[i+l+1][j][k2];
                                res = res > tRes ? res:tRes;
                            }                        
                        }
                        mm[i][j][k] = res;
                    }
                }
            }
        }
        cout << mm[0][n-1][m-1] << endl;
    }
    return 0;
}

 

 

dp区间算法

#include <iostream>
#include <cstdio>
#include <string>
#include <cmath>
#include <algorithm>
typedef long long ll;
typedef long long Array[22];
Array ob;
ll n,m,res,reco,rec,cur,maxs,temp;
using namespace std;
ll pow_dfs(ll i){
    ll ress=1;
    for(ll j=1;j<=i;j++){
        ress*=10;
    }
    return ress;
}
ll maxmin(ll a,ll b){
    return a>b?a:b;
}
void DFS(ll pos,ll rec,ll now){
    if(rec==m-1){
        ob[rec]=now;
        cur=1;
        for(int i=0;i<m;i++){
            cur*=ob[i];
        }
        maxs=maxmin(cur,maxs);
        return ;
    }
    if(pos>=reco)
        return ;
    DFS(pos+1,rec,now);
    ob[rec]=now/pow_dfs(reco-pos);
    now=now%pow_dfs(reco-pos);
    DFS(pos+1,rec+1,now);
}
int main(){
    ll T;
    //freopen("D://imput.txt","r",stdin);
    scanf("%lld",&T);
    while(T--){
        reco=1;maxs=0;
        scanf("%lld%lld",&n,&m);
        temp=n;
        while(temp/10){
            temp=temp/10;
            reco++;
        }
        DFS(1,0,n);
        printf("%lld",maxs);
        if(T!=0)
            printf("\n");
    }
    return 0;
}

 

posted @ 2015-06-28 17:10  sdlwlxf  阅读(644)  评论(0编辑  收藏  举报