[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.
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=0then begin writeln(I);halt;end;
13     end;
14 End.

[相关链接] 

[启发总结]
  1.  模型越抽象效率越高需要的能力越高
posted @ 2012-04-17 00:07  PerSeAwe  阅读(438)  评论(0编辑  收藏  举报