Vijos P1347 乘积最大

P1347乘积最大

描述

今年是国际数学联盟确定的“2000——世界数学年”,又恰逢我国著名数学家华罗庚先生诞辰90周年。在华罗庚先生的家乡江苏金坛,组织了一场别开生面的数学智力竞赛的活动,你的一个好朋友XZ也有幸得以参加。活动中,主持人给所有参加活动的选手出了这样一道题目:
设有一个长度N的数字串,要求选手使用K个乘号将它分成K+1个部分,找出一种分法,使得这K+1个部分的乘积能够为最大。

同时,为了帮助选手能够正确理解题意,主持人还举了如下的一个例子:
有一个数字串: 312,当N=3,K=1时会有以下两种分法:
1)3*12=36
2)31*2=62
这时,符合题目要求的结果是: 31*2=62
现在,请你帮助你的好朋友XZ设计一个程序,求得正确的答案。

格式

输入格式

程序的输入共有两行:
第一行共有2个自然数N,K (6<=N<=40,1<=K<=6)
第二行是一个长度为N的数字串。

输出格式

屏幕输出(结果显示在屏幕上),相对于输入,应输出所求得的最大乘积(一个自然数)。

样例1

样例输入1[复制]

4 2
1231

样例输出1[复制]

62

限制

1 second

来源

NOIP 2000年 第六届 普及组 第3题


设dp[i][j]为前i个数字插入j个乘号所得最大值
 
     
sum[i][j]为从i到j数字串所代表的数字
 
     
则dp[i][j] = max(dp[k][j - 1] * sum[k + 1][i]);
 
     
代码:

      
      
#include 
         
         
          
          
#include 
          
          
#include 
           
           
            
            
#include 
            
            
             
             
#include 
             
             
               #include 
              
                #include 
               
                 #include 
                
                  #include 
                 
                   #include 
                  
                    #include 
                   
                     #include 
                    
                      #include 
                     
                       #include 
                      
                        #include 
                       
                         #include 
                        
                          #include 
                         
                           #include 
                          
                            #define pi acos(-1.0) #define maxn (100 + 5) #define mol 1000000007 #define inf 50000 #define Lowbit(x) (x & (-x)) using namespace std; typedef long long int LLI; char str[maxn]; int sum[maxn][maxn],dp[maxn][maxn]; int main() { // freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); int n,k; scanf("%d%d",&n,&k); scanf("%s",str); for(int i = 0; i < n; i ++) { sum[i][i] = str[i] - '0'; for(int j = i + 1; j < n; j ++) sum[i][j] = sum[i][j - 1] * 10 + str[j] - '0'; } for(int i = 0; i < n; i ++) { dp[i][0] = sum[0][i]; for(int j = 1; j <= min(i,k); j ++) { for(int k1 = 0; k1 < i; k1 ++) dp[i][j] = max(dp[i][j],dp[k1][j - 1] * sum[k1 + 1][i]); } } printf("%d\n",dp[n - 1][k]); return 0; } 
                           
                          
                         
                        
                       
                      
                     
                    
                   
                  
                 
                
               
             
            
            
           
           
         
         



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值