求一递增整数序列,共36个数,第一个数为1,后面数逐渐增大
要求:任意两个整数的差(大整数减去小整数)均不相同
如:1 2 4 8 .....
求所有情况中第36个数(也就是最大数)最小时的解,即输出这36个数算法不难,关键是,如何让程序算法效率高,也就是如何在有限的时间内算出结果
计算时间最好在3个小时内
要求:任意两个整数的差(大整数减去小整数)均不相同
如:1 2 4 8 .....
求所有情况中第36个数(也就是最大数)最小时的解,即输出这36个数算法不难,关键是,如何让程序算法效率高,也就是如何在有限的时间内算出结果
计算时间最好在3个小时内
解决方案 »
- 如何把单选框的状态存入数据库
- 如何点击一个弹出窗口的确定按纽?高分求解!
- 如何实现对access库文件的压缩及解压(用vclzip?)?
- 关于图形控件,做这方面的可以看看。
- DLL 调用TCLIENTSOCKET onread 事件
- 如何在DELPHI中显示DWG(autoCAD图片)格式图片(300分)
- 为什么IDHTTP下载扩展名为.ini .bpl 的文件不行?
- **************sql问题******************简单的,大家帮忙
- 帮我看看这个SQL语句
- 请大家证实一下现在delphi有中文版的吗?帮助是中文的吗?
- 300分请教:如何在20万条数据表中抽样出1000条记录
- 怎么往表中写入记录
1+(1+(-1))+(1+0)=2
1+(1+(-1))+(1+0)+(1+1)=4
1+(1+(-1))+(1+0)+(1+1)+(1+2)=7
..
int j=1;
for(int i=-1;i<35;i++){
j=j+(1+i);
print(j);
}
哈阿,不用3小时把!?(631)
这个题目计算量的确太大了,抱歉,我也没有什么好的办法!关注中……
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TForm1 = class(TForm)
Memo1: TMemo;
Button1: TButton;
procedure FormCreate(Sender: TObject);
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
Flags:Array [1..1000000] of Boolean;//标志数组,记录差值是否被占用
Results:Array [1..36] of integer; //结果数组
function GetFirstFree:integer; //求出标志数组中第一个空缺
function GetNextFree(Cur:integer):integer;//求标志数组中下一个空缺
function CanUse(index,val:integer):Boolean; //判断结果数组中加入一个新的值是否合法
procedure AddNewVal(index,val:integer); //在结果数组中加入一个新的值
end;var
Form1: TForm1;implementation{$R *.dfm}procedure TForm1.FormCreate(Sender: TObject);
var
i:Integer;
begin
for i:=1 to 1000000 do
Flags[i]:=False;
end;function TForm1.GetFirstFree: integer;
var
i:integer;
begin
for i:=1 to 1000000 do
if not Flags[i] then
begin
Result:=i;
exit;
end;
result:=0;
end;function TForm1.GetNextFree(Cur: integer): integer;
var
i:integer;
begin
for i:=Cur+1 to 1000000 do
if not Flags[i] then
begin
Result:=i;
exit;
end;
result:=0;
end;procedure TForm1.Button1Click(Sender: TObject);
var
i,j,nextvalue:integer;
begin
Results[1]:=1;
i:=1;
for i:=2 to 36 do
begin
j:=GetFirstFree;
while not CanUse(i,Results[i-1]+j) do
j:=GetNextFree(j);
AddNewVal(i,Results[i-1]+j);
end;
for i:=1 to 36 do
Memo1.Lines.Add(inttostr(Results[i]));
end;function TForm1.CanUse(index, val: integer): Boolean;
var
i:integer;
begin
for i:=1 to index-1 do
if Flags[val-Results[i]] then
begin
result:=false;
exit;
end;
result:=true;
end;procedure TForm1.AddNewVal(index, val: integer);
var
i:integer;
begin
for i:=1 to index-1 do
Flags[val-Results[i]]:=true;
Results[index]:=val;
end;end.
老兄,你的算法好像不是最优的!
我要求第36个数最小!!!!!!
谢谢关注
这种算法的问题要比整天折腾那些控件有意思多了.
那位有高招阿???????
很不错的设想!
但是,有一点就是,最优值的时候并不能保证差值是个连续的序列.
如:个数为10时,最优解应该是
1 2 7 11 24 27 35 42 54 56 并不满足你的推断
还有5:
1 2 5 10 12
var
i:integer;
Test;array[0..35] of integer;
begin
Test[0]:=1;
for i:=1 to 35 do
test[i]:=Test[i-1]+i;
end;
谢谢关注,不过您好像没有看清题目要求求一递增整数序列,共36个数,第一个数为1,后面数逐渐增大
任意(是任意***)两个整数的差(大整数减去小整数)均不相同
如:1 2 4 8 .....
求所有情况中第36个数(也就是最大数)最小时的解,即输出这36个数求最小解!!!!
第36个数为631
第10个数为46
第5个数为11
这种思路有问题,你可以试试,5,怎么才能为11,看看此时前四个数是多少?
1,2,3...C(N,2),现在设N取值为X那么X-1应等于C(N,2)
所以X=C(N,2)+1,当N等于36时X=631。我觉得电脑是人类
思维的延伸,没必要每件事都要靠电脑。
不过,最优解并不能保证
差序列为
1,2,3...C(N,2),
最优解时,序列的通项为 n*(n-1)/2+1,即不管n为多少时, n*(n-1)/2+1为该序列的最小的第n项。To del_c_sharp(头大中......) :
个数为10时,最优解应该是
1 2 4 7 11 16 22 29 37 46 heifei()也能保证这一点,只是for(int i=-1;i<35;i++)大概应改为
for(int i=-1;i<34;i++)
1 2 4 7 11 16 22 29 37 46 并不满组条件
7-4 = 3 = 4-1有两个差相同!
请再看看题目,要求是任意两个
谢谢参与
你先把思路说说吧
要求每个差值均不相同且保证第n个数最小,那么只有差序列连续的时候
才能达到。就像n=4时1,3,6,7差序列为(7-6),(3-1),(6-3),
(7-3),(6-1),(7-1)而1,2,4,8的差序列为1,2,3,4,6,7,
‘5’被‘7’取代了,而‘7’只能是由最大值减最小值产生就导致了第四
个数为‘8’。
关键是给定长度n后
你并不一定能产生连续差序列
比如 n=5
我算出的最优解为
1 2 5 10 12
差
1 2 3 4 5 7 8 9 10 11 没有6你能给出一个长度为5 的差连续序列吗?
1 2 5 10 12。
1 3 8 9 12。
1 3 8 11 12。
1 4 5 10 12。
穷举来算恐怕很难。这个问题还可以换种说法。
求这样一个含有k个数的数列,满足下面条件:
1、任何相邻两个数的和 M 不再此数列中,并且数列仅有这一组相邻数之和等于 M。
2、满足条件1且数列的和最小。2、
任何相邻N个数的和 Total 不再此数列中,并且数列不再存在这样连续的 M 个数:这M个数之和为 Total。
Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
//思路:把任意两数的差存在一个叫‘h‘的数组里,结果存在一个叫Result的数组里
//每次我都取h中最大的数(当前最后一个数)和Result中最大的数项加得后一个Result数组中的结果-
//既下一个结果,并保证Result数组中任意两数的差不同。
//如果h数组中的的数是1,2,3...连续的,那么求出的Result必定最小
//因为 h数组中 只用到最大的数,so,只需用一个integer来存
iTemp,iMaxUsed:integer;
Result:array [1..36] of integer;implementation{$R *.DFM}procedure TForm1.Button1Click(Sender: TObject);
begin
Result[1]:=1;
Result[2]:=2;
iMaxUsed:=1;
for iTemp:=3 to 36 do
begin
iMaxUsed:=Result[iTemp-1]-1+iMaxUsed;
Result[iTemp]:=Result[iTemp-1]+iMaxUsed; end;
ShowMessage(IntToStr(Result[36]));end;end.
有问题的!
31-2=60-31=29
我按照他的思路,解出来的结果有问题
越往下差值相同的越多,算法有问题,正确的解法,正在进行中!
133, 215, 348, 563, 913, .......
用费波那切数列试验一下
A1 = 1
A2 = 3
An = A[n-1] + A[n-2]
36个数,要求任意两数差值不同,则差值之和为1+2+3+...+35,
设Num[n]=Num[n-1]+SubNum[m];
其中SubNum[m]始终是从未出现过的最小差值
最终结果为:1318
希望和各位大侠共同探讨,运行时间0.X秒
如
5的时候是12
1 3 8 11 12 符合要求的解12
1 4 5 10 12 符合要求的解12
1 2 5 10 12 符合要求的解12
1 3 8 9 12 符合要求的解126的时候是18
1 6 8 14 17 18 符合要求的解18
1 3 8 14 17 18 符合要求的解18
1 5 7 10 17 18 符合要求的解18
1 4 6 10 17 18 符合要求的解18 1 2 5 11 16 18 符合要求的解18
1 2 9 13 15 18 符合要求的解18
1 2 9 12 14 18 符合要求的解18
1 2 5 11 13 18 符合要求的解18
7的时候是26
1 3 8 16 22 25 26 符合要求的解26
1 3 6 15 19 25 26 符合要求的解26
1 3 7 10 15 25 26 符合要求的解26
1 5 10 16 23 24 26 符合要求的解26
1 2 8 12 21 24 26 符合要求的解26
1 2 12 17 20 24 26 符合要求的解26
1 4 5 13 19 24 26 符合要求的解26
1 2 5 11 19 24 26 符合要求的解26
1 3 8 14 22 23 26 符合要求的解26
1 3 4 11 17 22 26 符合要求的解26 8的时候是35
1 3 13 20 26 31 34 35 符合要求的解35
1 2 5 10 16 23 33 35 符合要求的解35
.................................
.................................所以不能使用递推的方法来计算,因为知道了n,没办法推算n+1的结果,用穷举的方法太慢了!
31-2=60-31
Yes,it's really interesting! Pay attention on it!
你确定第36个数小于1500的一定存在吗?
5个数的时候最小数是12。
1 2 5 10 12。
1 3 8 9 12。
1 4 5 10 12。
......
但我们如果考虑4个数时最小数就是7(1 3 6 7)
但我们如果考虑3个数时最小数就是4(1 3 4)结论:36个符合要求的序列中前35个数和只考虑35个数得到的序列不一定相同。
5个数的时候最小数是12。
1 2 5 10 12。
1 3 8 9 12。
1 4 5 10 12。
...
如果只考虑4个数时最小数就是7(1 3 6 7)
如果只考虑3个数时最小数就是4(1 2 4)结论:36个符合要求的序列(第36个数最小)中前35个数 与 只考虑35个数得到第序列不一定相同,即不能简单的从前往后取数,而需要整体考虑这36个数。
var
TempValue:integer;
i:integer;
begin
Result:=Start;
TempValue := Num;
while TempValue >=1 do
begin
inc(Result,TempValue);
dec(TempValue,Step);
end;
end;1
37
72
106
139
171
202
232
261
289
316
342
367
391
414
436
457
477
496
514
531
547
562
576
589
601
612
622
631
639
646
652
657
661
664
666
667
var
TempValue:integer;
i:integer;
begin
Result:=Start;
TempValue := Num-1;
while TempValue >=1 do
begin
inc(Result,TempValue);
dec(TempValue,Step);
end;
end;1
36
70
103
135
166
196
225
253
280
306
331
355
378
400
421
441
460
478
495
511
526
540
553
565
576
586
595
603
610
616
621
625
628
630
631
631-628=628-625=3
631-625=616-610=6
630-625=621-616=5
.................
这种方法肯定不行,你不能保证任意两个数的差不相等
unit Unit1;interfaceuses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;type
TForm1 = class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
Edit2: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;var
Form1: TForm1;
intv:array[1..8000] of integer;
d:array[1..36] of integer;implementation{$R *.dfm}function intv_ok(vl,j:integer):boolean;
var
i,m,c:integer;begin
c:=(j-2)*(j-1) div 2;
result:=true;
if j>=3 then
begin
for i:=1 to c do
for m:=1 to j-1 do
if vl-d[m]=intv[i] then
begin
result:=false;
exit;
end;
end;
end;procedure intv_ins(vl,j:integer);
var
i,c1,c2:integer;
begin
c1:=(j-2)*(j-1) div 2+1 ;
c2:=(j-2)*(j-1) div 2+j-1;
for i:=c1 to c2 do
intv[i]:=vl-d[i-(j-2)*(j-1) div 2];
end;
procedure TForm1.Button1Click(Sender: TObject);
var
rs:array[1..36] of integer;
i,j,vl,max36:integer;
back:boolean;
c:integer;
l:longint;
begin
l:=GetTickCount ;
c:=strtoint(edit1.Text);
max36:=3000;
for i:=1 to 36 do
begin
d[i]:=1;
intv[i]:=0;
end;
intv[1]:=1;
j:=2;
repeat
vl:=d[j];
back:=false;
while ((vl<=d[j-1])or( not intv_ok(vl,j))) do
begin
vl:=vl+1;
if vl>max36 then
begin j:=j-1;
d[j]:=d[j]+1; back:=true;
break;
end;
end; if not back then if vl>max36 then
begin j:=j-1;
d[j]:=d[j]+1; end
else
begin
d[j]:=vl;
intv_ins(vl,j);
j:=j+1;
if j=c+1 then
begin
if d[c]<max36 then
begin
for i:=1 to c do
rs[i]:=d[i];
max36:=d[c];
if max36<strtoint(edit2.Text) then j:=2;
memo1.Clear ;
for i:=1 to c do
memo1.Lines.Add(inttostr(rs[i]));
memo1.Lines.SaveToFile('data.txt');
Application.ProcessMessages ;
end;
j:=j-2;
d[j]:=d[j]+1; end
else d[j]:=d[j-1]+1;
end;
until (j<2) ;
memo1.Clear ;
for i:=1 to c do
memo1.Lines.Add(inttostr(rs[i]));
showmessage(inttostr(GetTickCount-l));
end;end.
其实我们考察下列命题:
有两个整数序列A(A1,A2,A3 ... A(n)) 和 B(B1,B2,... B(n-1)),A1 = 1
满足A(i+1) = A(i)+B(i) 其中 i = 1,2,3, .... n-1,
且B(i)<>B(j), B(i)>0 i,j = 1,2,3 ... n-1
求取A(n)的Min最优解。
当n=36时,命题成为楼上兄弟[ del_c_sharp (头大中......)]的题目。
其实这个命题求不难,由于A1 = 1,
A(n) = B(n-1)+A(n-1)
= B(n-1)+B(n-2)+A(n-2)
= B(n-1)+B(n-2)+B(n-3)+ ... +B2+B1+A1
于是,求A(n)的Min解,变成了求 B1+B2+ ... +B(n-1)的最小值的解。
由于B(i)<>B(j),B(i)>0,显然,B1+B2+ ...+ B(n-1)的最小值的解是 1+2+...+(n-1)
于是A(n)= 1+ 1+ 2 + ... + (n-1)
下面有下段程序,用笨办法来实现一种序列,最优解序列有多种,这只是其中最简单的一种:unit .........implementation
const
nBound:integer = 36;var
nA,nB:array[0..35] of integer; //nA 存放序列的数,nB存放差值
i:integer;
procedure TForm1.Button1Click(Sender: TObject);
var
i,j:integer;
s1,s2:string;
begin
nB[0] := 1;
s1 := IntToStr(nA[0])+', ';
for i:= 1 to nBound-1 do begin
nA[i] := nA[i-1];
j := 0;
if i>1 then
nB[i-1] := nB[i-2];
while (j<i-1) do begin //检查有没有相同的差值
if (nB[j]= nB[i-1]) then Inc(nB[i-1]);
inc(j);
end;
nA[i] := nA[i-1]+ nB[i-1];
s1 := s1+ IntToStr(nA[i]);
if i<(nBound-1) then
s2 := s2+ IntToStr(nB[i-1]);
if i <> (nBound-1) then
begin
s1 := s1+', ';
if i<(nBound-2) then
s2 := s2+', ';
end;
end;
Memo1.Lines.Add('');
Memo1.Lines.Add('数据序列是:');
Memo1.Lines.Add(s1);
Memo1.Lines.Add('差是:');
Memo1.Lines.add(s2);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
Memo1.Lines.Clear;
end;initialization
for i := 0 to nBound-1 do
begin
nA[i] :=0; nB[i] := -1;
end;
nA[0] := 1;
end.
结果是:
数据序列是:
1, 2, 4, 7, 11, 16, 22, 29, 37, 46, 56, 67, 79, 92, 106, 121, 137, 154, 172, 191, 211, 232, 254, 277, 301, 326, 352, 379, 407, 436, 466, 497, 529, 562, 596, 631
差是:
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34,35
谢谢参与,不过你还是没有看清题目,我已经说了好多次.
任意两个数的差均不同1,2,4,7,.....4-1=3=7-4