68.最大k乘积问题 (15分)
C时间限制:3000 毫秒 | C内存限制:3000 Kb
题目内容:
设I是一个n位十进制整数.如果将I划分为k段,则可得到k个整数.这k个整数的乘积称为I的一个k乘积.试设计一个算法,对于给定
的I和k ,求出I的最大k乘积.
Input
输入的第1行中有2个正整数n和k.正整数n是序列的长度;正整数k是分割的段数.接下来的一行中是一个n位十进制整数.(n<=10)
Output
输出计算结果,第1行中的数是计算出的最大k乘积.
n位十进制整数.(n<=10)
输入描述
输入的第1行中有2个正整数n和k.正整数n是序列的长度;正整数k是分割的段数.接下来的一行中是一个
输出描述
输出计算结果,第1行中的数是计算出的最大k乘积.
输入样例
2 1
15
输出样例
15*/
#include<stdio.h>
#include<iostream>
#include<string.h>
using namespace std;
int n,m;
string s;
int a[15];
int dp[15][15];
int cal(int s,int e){
int ans = a[s];
for(int i=s+1;i<=e;i++){
ans=ans*10+a[i];
}
return ans;
}
int main(){
cin>>n>>m;
cin>>s;
memset(a,0,sizeof(a));
for(int i=1;i<=n;i++){
a[i] = s[i-1]-'0';
}
for(int i=1;i<=n;i++){
dp[i][1] = cal(1,i);
}
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(i==j)
dp[i][j] = dp[i-1][j-1]*cal(i,i);
else if(i<j)
dp[i][j] = 0;
else{//i>j
if(j!=1)
dp[i][j]=0;
for(int kk=1;kk<i;kk++){
if(kk<j-1)
dp[kk][j-1] = 0;
dp[i][j]=max(dp[kk][j-1]*cal(kk+1,j),dp[i][j]);//将分为j段的问题化简为分为j-1段,大问题化为小问题
}
}
}
}
cout<<dp[n][m]<<endl;
return 0;
}
思路:
cal(i,j)记录的是一串数字从第i位到第j位的数,
举例:1234
cal(2,3) 就是23 cal(2,4)就是234
列表
j\i | 1 | 2 | 3 | 4 |
---|---|---|---|---|
1 | 1 | 12 | 123 | 1234 |
2 | 0 | 2 | 36 | 492 |
3 | 0 | 0 | 6 | 144 |
4 | 0 | 0 | 0 | 24 |
再注意一下细节问题