您的位置:首页 > 编程语言 > C语言/C++

整数划分(文件名:separate.c/cpp/pas)

2011-08-26 22:04 381 查看

整数划分(文件名:separate.c/cpp/pas)

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

输入数据:

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

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

输出数据:

对于每组数据

第一行输出最大值。

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

样例

输入文件:separate.in

1

199 2

输出文件:separate.out

171

19 9

===========================

输出方案的DP

----------------------

f[i,j]表示前i个,分j次的最大价值....

v[i,j]表示这一阶段是由...转换而来的...

-----------------------------------------------------

注意数据范围...

最后在递归输出解...

=========================================

var
m:longint;
n:int64;
t,t1:longint;
st:ansistring;
g:array[1..20,1..20]of int64;
f,v:array[0..20,0..20]of int64;
procedure init;
begin
assign(input,'separate.in');
assign(output,'separate.out');
reset(input); rewrite(output);
end;

procedure terminate;
begin
close(input); close(output);
halt;
end;

function min(a,b:longint):longint;
begin
if a<b then exit(a);
exit(b);
end;

function max(a,b:int64):int64;
begin
if a>b then exit(a);
exit(b);
end;

procedure print(l,m:int64);
var
i:longint;
begin
if m=0 then exit;
print(v[l,m],m-1);
for i:=v[l,m]+1 to l do write(st[i]);
write(' ');
end;

procedure main;
var
i,j,k:longint;
len:longint;
sum:int64;
begin
readln(t1);
for t:=1 to t1 do
begin
readln(n,m);
str(n,st);
len:=length(st);
for i:=1 to len do
begin
sum:=0;
for j:=i to len do
begin
sum:=sum*10+ord(st[j])-48;
g[i,j]:=sum;
end;
end;

for i:=0 to len do
for j:=0 to m do
f[i,j]:=-1;
f[0,0]:=1;

for i:=1 to len do
for k:=1 to min(m,i) do
for j:=1 to i do
begin
//writeln(i,' ',j,' ',k);
//writeln(f[i,k],' ',f[j-1,k-1],' ',g[j,i]);
if f[j-1,k-1]*g[j,i]>f[i,k] then
begin
f[i,k]:=f[j-1,k-1]*g[j,i];
v[i,k]:=j-1;
end;
//writeln(f[i,k],' ',f[j-1,k-1]);
//writeln;
end;
writeln(f[len,m]);
print(len,m);
end;
end;

begin
init;
main;
terminate;
end.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: