问题描述: | 大家知道,黄药师不仅武功高超,而且酷爱音乐和诗歌。看到桃花岛来了个新客人,而且 不是靠真武功进来的,就准备为难为难你。 | |
数据输入: | 第1行为一个整数N(1 <= N <= 4000),代表黄药师写的诗歌的句子数。 | |
结果输出: | 一行一个整数k,为黄药师最多能够得到的四行诗个数。 | |
样例: | 15 1 2 3 1 2 1 2 3 3 2 1 1 3 2 2 | 3 |
核心思想: | 有两个方法:动规(没看懂),贪心(是个规律,依旧不懂) |
//动规 var n:longint; a:array[0..4001] of longint; f:array[0..4001] of longint; can:array[0..4001,0..4001] of boolean; function max(x,y:longint):longint; begin if x>y then exit(x) else exit(y); end; procedure init; var i,j:longint; flag:boolean; begin readln(n); for i:=1 to n do read(a[i]); for i:=1 to n do begin flag:=false; for j:=i+1 to n do if (flag) or (a[i]=a[j]) then begin can[i,j]:=true; flag:=true; end else can[i,j]:=false; end; end; function check(ed,st:longint):boolean; var i:longint; begin for i:=st to ed do if can[i,ed] then exit(true); exit(false); end; procedure main; var i,j:longint; flag:boolean; begin fillchar(f,sizeof(f),0); for i:=1 to n do begin f[i]:=f[i-1]; flag:=false; for j:=i-1 downto 1 do begin if a[i]=a[j] then flag:=true; if i-j+1<4 then continue; if (a[i]<>a[j]) and (flag) and (can[j,i-1]) then begin f[i]:=max(f[i],f[j-1]+1); break; end; if (a[i]=a[j]) and (check(i-1,j+1)) then begin f[i]:=max(f[i],f[j-1]+1); break; end; end; end; writeln(f[n]); end; begin init; main; //=========================================================== //贪心 var i,s,k,m,n,z:longint; a:array[0..10000] of longint; begin readln(n); for i := 1 to n do begin read(s); if (a[s]>m) and (k<>s) then begin inc(z); if not odd(z) then m := i; k := s; end else begin if k=s then k := 0; a[s] := i; end; end; writeln(z div 2); end. 题目来源:NDK 1330