最大K乘积问题(DP专题)

最大K乘积问题:

 设I是一个n位十进制整数。如果将I划分为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积。试设计一个算法,对于给定的I和k,求出I的最大k乘积。


编程任务:
       对于给定的I 和k,编程计算I 的最大k 乘积。

Input
输入的第1 行中有2个正整数n和k。正整数n是序列的长度;正整数k是分割的段数。接下来的一行中是一个n位十进制整数。(n<=10) 
Output
计算出的最大k乘积。 
Sample Input
2 1
15Sample Output
15Source
FJOI 2005 
*/
/*
解题思路:DP 
设w(h,k) 表示: 从第1位到第K位所组成的十进制数,设m(i,j)表示前i位(1-i)分成j段所得的最大乘积,则可得到如下经典的DP方程:
if(j==1)  m(i,j) = w(1,i) ;
if(j >=1 && j<=i) m(i,j) = max{m(d,j-1)*m(d+1,i)} 其中: 1<=d< i (即从1开始一直到i-1 中找最大值
else if(i < j) m(i,j) = 0 ; 
*/


#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< string .h >
#define  MAXN 51
#define  MAXK 10

long  m[MAXK][MAXN] = {{0,0}}  ;  /*初始化操作*/
long  w[MAXN][MAXN] = {{0,0}}  ;
 
void  maxdp( int  n, int  k, int   * a)
{
     
int i,j,d,h,q,t,s;
     
long temp,max;
     
for(i=1; i<= n ; i++/*分成1段*/
     m[i][
1= w[1][i];
     
 
    
     
for(i=1 ; i<= n ; i++/* DP 过程*/
      
for(j=2; j<= k ; j++)
      
{
               max 
= 0;
   
               
for(d=1; d < i ; d++)
                
if ( (temp = m[d][j-1]*w[d+1][i]) > max)
                       max 
= temp ;
               m[i][j] 
= max ;
              
               
      }

      
}



                       
                       
                       
int  main( void )
{
  
int n,k,i,j;
    
int a[MAXN]={0},la=0;
   
char c ;
   scanf(
"%d %d ",&n,&k);

    
while ( ( c=getchar() )!=' '/*读入数据*/
    
{
          a[
++la] = c-'0' ;
    }

    
    
for(i=1 ; i<= n; i++)
    
{
            w[i][i]
= a[i] ;
            
for(j=i+1 ; j<= n; j++)
            w[i][j] 
= w[i][j-1]*10 + a[j] ;
    }

    
    
/*
    for(i=1 ; i<= n; i++)
    {
            for(j=1 ; j<= n; j++)
            printf("%d ",w[i][j]);
            printf(" ");
    }
    
*/

    
    maxdp(n,k,a) ;

    
    printf(
"%ld ",m[n][k]) ;
    
    
/*system("pause");*/
    
    
return  0;
}


/*NO.2*/
/*
 设I是一个n位十进制整数。如果将I划分为k段,则可得到k个整数。这k个整数的乘积称为I的一个k乘积。试设计一个算法,对于给定的I和k,求出I的最大k乘积。


编程任务:
       对于给定的I 和k,编程计算I 的最大k 乘积。

Input
输入的第1 行中有2个正整数n和k。正整数n是序列的长度;正整数k是分割的段数。接下来的一行中是一个n位十进制整数。(n<=10) 
Output
计算出的最大k乘积。 
Sample Input
2 1
15Sample Output
15Source
FJOI 2005 
*/

#include 
< stdio.h >
#include 
< stdlib.h >
#include 
< string .h >
#define  MAXN 51
#define  MAXK 10

long  m[MAXK][MAXN] = {{0,0}}  ;  /*初始化操作*/
long  w[MAXN][MAXN] = {{0,0}}  ;
 
void  maxdp( int  n, int  k, int   * a)
{
     
int i,j,d,h,q,t,s;
     
long temp,max;
     
for(i=1; i<= n ; i++/*初始,分成1段*/
     m[i][
1= w[1][i];
     
 
    
     
for(i=1 ; i<= n ; i++/* DP 过程*/
      
for(j=2; j<= k ; j++)
      
if( i >= j) /*剪枝*/
      
{
               max 
= 0;
   
               
for(d=1; d < i ; d++)
                
if ( (temp = m[d][j-1]*w[d+1][i]) > max)
                       max 
= temp ;
               m[i][j] 
= max ;
              
               
      }

      
}



                       
                       
                       
int  main( void )
{
    
int n,k,i,j;
    
int a[MAXN]={0},la=0;
    
char c ;
    scanf(
"%d %d ",&n,&k);
    
    
while ( ( c=getchar() )!=' '/*读入数据*/
    
{
          a[
++la] = c-'0' ;
    }

    
    
for(i=1 ; i<= n; i++)
    
{
            w[i][i]
= a[i] ;
            
for(j=i+1 ; j<= n; j++)
            w[i][j] 
= w[i][j-1]*10 + a[j] ;
    }

    
    
/*
    for(i=1 ; i<= n; i++)
    {
            for(j=1 ; j<= n; j++)
            printf("%d ",w[i][j]);
            printf(" ");
    }
    
*/

    
    maxdp(n,k,a) ;

    
    printf(
"%ld ",m[n][k]) ;
    
    
/*system("pause");*/
    
    
return  0;
}


 

你可能感兴趣的:(编程,算法,String,System,input,output)