区间DP——整数划分(使乘积最大)


#include <iostream>
#include <cstring>
#include <cmath>
using namespace std;

#define SIZE 20

char arr[SIZE];
int Num[SIZE][SIZE];
int DP[SIZE][SIZE];

int len;
int cutNum;


void getNum(){
    
    int mid;
    
    for( int i = 1; i <= len; ++i ) 
        Num[i][i] = arr[i] - '0';
        
    for( int dist = 1; dist <= len; ++dist ){
        for( int start = 1; ( start + dist ) <= len; ++start ){
            
            mid = ( start + start + dist ) / 2;
            Num[start][start + dist] = Num[start][mid] * pow( 10, ( start + dist - mid ) ) + Num[mid + 1][start + dist];
            
        }
    }
}


void cal(){
    
    for( int i = 1; i <= len; ++i )
        DP[i][0] = Num[1][i];
        
    for( int cutNum = 0; cutNum <= len - 1 ; ++cutNum ){
        for( int end = 1; end <= len; ++end ){
            for( int pos = 1; pos <= end; ++pos ){
                if( end > cutNum && pos > ( cutNum - 1 ) && ( pos + 1 ) <= end ) 
                    DP[end][cutNum] = max( DP[end][cutNum], DP[pos][cutNum - 1] * Num[pos + 1][end] );
            }
        }
    }
}


int main(){
    
    memset( DP, 0, sizeof(DP) );
    
    cin >> len >> cutNum;
    
    for( int i = 1; i <= len; ++i ) 
        cin >> arr[i];
        
    getNum();
    cal();
    
    cout << "ANS: " << DP[len][cutNum - 1] << endl;
    
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值