Problem 1208 最大k乘积问题
Accept: 356 Submit: 828
Time Limit: 1000 mSec Memory Limit : 32768 KB
Problem Description
设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)
第1行中有2个正整数n和k。正整数n是序列的长度;正整数k是分割的断数。
接下来的一行中是一个n位十进制整数。(n<=10)
Output
对于每组数据,输出计算出的最大k乘积。
Sample Input
2 115
Sample Output
15
Source
FJ CFCS 2005首先这个题目的dp[i][j]中存的应该是从末尾到i位分k段的最大乘积
前面数字为一段,用nik[i][j]来表示从i位到j位的数字
于是状态转移方程为 dp[i][j]=max{dp[j-1~i-1][j-1]*nik[j~i][i]}
这个问题中待分解的数比较小
而一个数分解后的乘积一定会比本身小
所以int型足够了
#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int M=11;
int nik[M][M];
int dp[M][M];
int main()
{
int ws,k;
int n;
while(scanf("%d%d%d",&ws,&k,&n)!=EOF)
{
memset(dp,0,sizeof(dp));
if(k==1)
{
printf("%d\n",n);
continue;
}
else
for(int i=1;i<=ws;i++)
{
int p=10;
for(int j=i;j<=ws;j++)
{
nik[i][j]=n%p;
p*=10;
}
n/=10;
}
for(int i=1;i<=ws;i++)
{
dp[i][1]=nik[1][i];
}
for(int i=2;i<=k;i++)
{
for(int j=1;j<=ws;j++)
{
int maxn=0;
for(int k=1;k<j;k++)
{
maxn=max(dp[k][i-1]*nik[k+1][j],maxn);
}
dp[j][i]=maxn;
}
}
printf("%d\n",dp[ws][k]);
}
return 0;
}