[Poj]1844——数学
[题目大意]
- 给定一个数列,从1到N,可以决定数字前的符号是正还是负,求最小的N可以使得数列的结果为S
[分析题解]
- 一开始想用F[I,J]表示到从1..I,结果J可不可以达到。然后滚动数组优化,然后加个小剪枝,转移一下。900+Ms过了。见Code1
- 看discuss时发现这道题目的正解,真是叫人拍案叫绝。原来这是一道非常小清新的数学题。
- 当我们改变数字前的符号时,引起的变化总是偶数,所以第一个满足sigma(1..N)-S是偶数的N就是答案。因为只要满足这个条件,总可以通过改变一个符号得到合法的序列。真好,真好。具体看Discuss中的一个讨论。
[个人代码]
Code1
1 //10082669 perseawe 1844 Accepted 2044K 954MS Pascal 519B 2012-04-16 23:53:18
2
3 Const
4 Max=200000;
5
6 Var
7 S,I,J,t,Sum:Longint;
8 F:Array [0..1,-Max..Max] of Boolean;
9 Use:Array [-Max..Max] of Boolean;
10
11 Begin
12 readln(S);
13 Fillchar(F,sizeof(F),False);
14 Fillchar(Use,Sizeof(Use),False);
15 F[0,0]:=True;Sum:=0;
16 For I:=1 to MaxLongint do
17 begin
18 t:=I and 1;
19 Move(Use[-Max],F[t,-Max],Max+Max);
20 For J:=-Sum to Sum do If F[1-t,J] then begin F[t,J-I]:=True;F[t,J+I]:=True;end;
21 Inc(sum,I);
22 If F[t,S] then begin writeln(I);Halt;end;
23 end;
24 End.
2
3 Const
4 Max=200000;
5
6 Var
7 S,I,J,t,Sum:Longint;
8 F:Array [0..1,-Max..Max] of Boolean;
9 Use:Array [-Max..Max] of Boolean;
10
11 Begin
12 readln(S);
13 Fillchar(F,sizeof(F),False);
14 Fillchar(Use,Sizeof(Use),False);
15 F[0,0]:=True;Sum:=0;
16 For I:=1 to MaxLongint do
17 begin
18 t:=I and 1;
19 Move(Use[-Max],F[t,-Max],Max+Max);
20 For J:=-Sum to Sum do If F[1-t,J] then begin F[t,J-I]:=True;F[t,J+I]:=True;end;
21 Inc(sum,I);
22 If F[t,S] then begin writeln(I);Halt;end;
23 end;
24 End.
Code2
1 //10082679 perseawe 1844 Accepted 872K 16MS Pascal 210B 2012-04-16 23:55:35
2
3 Var
4 S,Sum,I:Longint;
5
6 Begin
7 readln(S);
8 Sum:=0;
9 For I:=1 to MaxLongint do
10 begin
11 Inc(Sum,I);
12 If (Sum-S>=0)and((Sum-S) and 1=0) then begin writeln(I);halt;end;
13 end;
14 End.
2
3 Var
4 S,Sum,I:Longint;
5
6 Begin
7 readln(S);
8 Sum:=0;
9 For I:=1 to MaxLongint do
10 begin
11 Inc(Sum,I);
12 If (Sum-S>=0)and((Sum-S) and 1=0) then begin writeln(I);halt;end;
13 end;
14 End.
[相关链接]
[启发总结]
- 模型越抽象效率越高需要的能力越高
——————————————————————————————————————
你说,我们的存在,永不消逝。对吧?
如果,我们都在努力创造了存在。我们,会幸福的。对吧?