依据条件,只通用穷举,这样,搜索的时间有点长。特别是N>? 时,更加如此.......
解决方案 »
- 一个整形值存储在Double类型的变量里,如何将其转换为Int64类型?
- 关于CLIENTSOCKET通信的问题,高手请进
- 请问可以通过源码判断Delphi开发环境的版本吗?
- 这样标准的语句怎么会有错?????
- 如何控制ListView的滚动。
- %%%%%简单问题!
- 在先等候求救!!从comobox选择时,能不能判定出用户选择了那一行的???急急急急急急急急~
- 更改,add,delete数据库字段名,数据库类型为delphi自带的那种,扩展名是.db。
- 数码音箱mp3排序问题 请大家多帮忙指点 谢啦
- 麻烦各位帮助我解决两个小问题,见者有分
- Delphi 怎么 Hook 指定句柄窗体的消息
- 我有一个Delphi程序,它输出的txt,用文本文件打开是乱码,怎么办?
对于序列W[i]={w1,w2,...,wN},令di=wi-w1,
可组成差项列D[i]={d1,d2,...,dN},(这里d1=0)
现在我们把原题用w1和di重新写一遍,成为:
对于正数N,查找正整数W1和整数序列0=d1<d2<d3<...<dN,使得序列
{w1,w1+d2,w1+d3,...,w1+dN}和矩阵(这里矩阵对角线上的元素可不用考虑,用NA表示它)
-----------------------------------------------------------------------------------
NA , 2w1+2d1-w1-d2 , 2w1+2d1-w1-d3 , 2w1+2d1-w1-d4 , ... , 2w1+2d1-w1-dN
2w1+2d2-w1-d1 , NA , 2w1+2d2-w1-d3 , 2w1+2d2-w1-d4 , ... , 2w1+2d2-w1-dN
2w1+2d3-w1-d1 , 2w1+2d3-w1-d2 , NA , 2w1+2d3-w1-d4 , ... , 2w1+2d3-w1-dN
2w1+2d4-w1-d1 , 2w1+2d4-w1-d2 , 2w1+2d4-w1-d3 , NA , ... , 2w1+2d4-w1-dN
...
2w1+2dN-w1-d1 , 2w1+2dN-w1-d2 , 2w1+2dN-w1-d3 , 2w1+2dN-w1-d4 , ... , NA
-----------------------------------------------------------------------------------
之间没有重合元素。
另外,根据wN<1.5w1,有w1+dN<1.5w1,即dN<0.5w1 或 w1>2dN。
现在从上面把w1全部减去(反正只要求出dN之后,给个>2dN的值做w1就可以满足条件了)
题目变形为
对于正整数N,查找整数序列0=d1<d2<d3<...<dN,使得序列
{d1,d2,d3,...,dN}和矩阵(这里矩阵对角线上的元素可不用考虑,用NA表示它)
-----------------------------------------------------------------------------------
NA , 2d1-d2 , 2d1-d3 , 2d1-d4 , ... , 2d1-dN
2d2-d1 , NA , 2d2-d3 , 2d2-d4 , ... , 2d2-dN
2d3-d1 , 2d3-d2 , NA , 2d3-d4 , ... , 2d3-dN
2d4-d1 , 2d4-d2 , 2d4-d3 , NA , ... , 2d4-dN
...
2dN-d1 , 2dN-d2 , 2dN-d3 , 2dN-d4 , ... , NA
-----------------------------------------------------------------------------------
中没有相同元素。也就是说
对于数组{d1,d2,d3,...,dN}而言,要求任何2di-dj不能出现在原来数组里面
这个可以画表格来找出其中的一组解
d, d*2
0, 0
1, 2
3, 6 (不能为2,因为2-2=0已经出现在d里面了,可以为3因为2-3=-1不在d里面)
4, 8 (6-4=2不在d里面,0-4,2-4均不在d里面)
9, 18 (6-5=1, 6-6=0, 8-7=1, 8-8=0都在d里面,因此取9)
10,20 (18-10=8不在d里面)
12,24 (18-11=7在d里面, 18-12=6, 20-12=8均不在d里面)
...
最后求出dN了之后,另w1=dN*2+1就可以推导出W序列的一组解了。这个思路,可以通过2重循环实现,时间复杂度差不多是O(N^3),空间上需要2个数组(1个放d,一个放d*2,如果存储紧张的话也可以只用一个数组),空间复杂度为O(N)。type
TIntArray = array of Integer;//check whether a value is allowed in array d
function isValidValue(value: Integer; d, d2: array of Integer; maxIndex: Integer): Boolean;
var
i, j: Integer;
v: Integer;
begin
Result:= true;
for i:= maxIndex downto 0 do
begin
if d2[i]<value then
exit;
v:= d2[i]-value;
for j:= 0 to maxIndex do
begin
if d[j]=v then
begin
Result:= false;
exit;
end ;
end ;
end ;
end;//get sequence of w
function getSequence(N: Integer): TIntArray;
var
d, d2: array of Integer;
w1: Integer;
i: Integer;
begin
setLength(d, N);
setLength(d2,N);
d[0]:= 0;
d2[0]:= d[0]*2;
for i:= 1 to N-1 do
begin
d[i]:= d[i-1]+1;
while not isValidValue(d[i], d, d2, i-1) do
begin
inc(d[i]);
end;
d2[i]:= d[i]*2;
end ;
setLength(Result, N);
w1:= d2[N-1]+1;
for i:= 0 to N-1 do
begin
Result[i]:= w1+d[i];
end ;
setLength(d,0);
setLength(d2,0);
end ;
证明为方法为数学归纳法:假设当N=k时存在符合条件的d={0, d1, d2, ..., dk},则当N=k+1时,序列{0, d1, d2, ..., dk, dk*2+1)必然满足条件 -- 因为很明显的, dk*2+1 - ds (s<=k)必然大于dk, 而其它任何元素ds*2必然<dk*2+1因此不可能发生重复。根据这个思路的话,如果不介意数字变得过大的话,直接令d[k]=d[k-1]*2+1可以在O(N)的时间内求序列。