您的位置:首页 > 其它

整数划分

2015-07-18 13:29 337 查看

整数划分

时间限制: 1 Sec 内存限制: 128 MB

题目描述

如何把一个正整数N(N长度<20)划分为M(M>1)个部分,使这N个部分的乘积最大。N、M从键盘输入,输出最大值及一种划分方式。

输入数据:

第一行一个正整数T(T<=10000),表示有T组数据。
接下来T行每行两个正整数N,M。


输入

第一行一个正整数T(T<=10000),表示有T组数据。

接下来T行每行两个正整数N,M。

输出

对于每组数据

第一行输出最大值。

第二行输出划分方案,将N按顺序分成M个数输出,两个数之间用空格格开。

样例输入

1

199 2

样例输出

171

19 9

题解

f[i,j]:取i到j的数字组成的数f[i,j]:取i到j的数字组成的数

dp[i,j,1]:前i个数字分成j个乘积的最大值dp[i,j,1]:前i个数字分成j个乘积的最大值

dp[i,j,2]:记录dp[i,j,1]的值是由谁传递来的dp[i,j,2]:记录dp[i,j,1]的值是由谁传递来的

dp[i,j,1]=max(dp[i,j,1],dp[k,j−1]∗f[k+1,i]) 1≤k≤i−1dp[i,j,1]=max(dp[i,j,1],dp[k,j-1]*f[k+1,i]) \ \ \text{$1\le k\le i-1$}

dp[i,j,2]=k dp[i,j,1]<dp[k,j−1]∗f[k+1,i]dp[i,j,2]=k\ \ {dp[i,j,1]

var
dp:array[0..20,0..20,1..2]of int64;
f:array[0..20,0..20]of int64;
x:array[0..20]of string;
i,j,k,l:longint;
t,m,s,len:longint;
n,v:int64;
st:string;
function max(a,b:int64):int64;
begin
if a>b
then exit(a)
else exit(b);
end;

begin
readln(t);
for l:=1 to t do
begin
readln(n,m); str(n,st);
for i:=1 to length(st) do
for j:=1 to length(st) do
val(copy(st,i,j-i+1),f[i,j]);
for i:=1 to 20 do
for j:=1 to 20 do
if (j=1)and(i<=length(st))
then dp[i,j,1]:=f[1,i]
else dp[i,j,1]:=0;
for i:=2 to length(st) do
for j:=2 to m do
for k:=1 to i-1 do
begin
{dp[i,j,1]:=max(dp[i,j,1],dp[k,j-1,1]*f[k+1,i]);}
if dp[k,j-1,1]*f[k+1,i]>dp[i,j,1]
then
begin
dp[i,j,1]:=dp[k,j-1,1]*f[k+1,i];
dp[i,j,2]:=k;
end;
end;
writeln(dp[length(st),m,1]);
if dp[length(st),m,1]=0
then begin
for i:=1 to length(st) do
write(st[i],' ');
writeln;
end
else begin
i:=length(st); j:=m; len:=0;
while j>1 do
begin
s:=dp[i,j,2];
inc(len);
x[len]:=copy(st,s+1,length(st)-s);
st:=copy(st,1,s);
i:=s; dec(j);
end;
inc(len); x[len]:=st;
for i:=len downto 1 do
write(x[i],' ');
writeln; end;
end;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: