Đang tải... (xem toàn văn)
ÁP DỤNG QUY HOẠCH ĐỘNG CHO DÃY SỐTRÊN MẢNG 1 CHIỀUDẠNG 1: DÃY CON LIÊN TỤC1. Bài toán Tính tổng của dãy sốCho dãy số nguyên gồm n phần tử a1, a2, …, an và hai số nguyên dương p và q (1 p q n).Yêu cầu: Hãy tính tổng của các phần tử liên tiếp từ ap … aq.Dữ liệu: Vào từ file văn bản SUM.INP có cấu trúc như sau: Dòng 1: Ghi số nguyên dương n và k, hai số được ghi cách nhau một dấu cách. (1 k, n 105) Dòng 2: Ghi n số nguyên a1, a2, …, an, các số được ghi cách nhau ít nhất một dấu cách (32000 ai 32000). Dòng thứ i trong k dòng tiếp theo: Mỗi dòng ghi hai số nguyên dương pi và qi, hai số được ghi cách nhau một dấu cách (1 pi qi n). Kết quả: Ghi ra file văn bản SUM.OUT theo cấu trúc như sau: Dữ liệu được ghi trên k dòng: Dòng thứ i ghi một số nguyên là tổng giá trị của các phần tử trong đoạn Ví dụ:SUM.INPSUM.OUT5 32 9 3 5 81 52 34 42165Code tham khảo: Độ phức tạp O(n+k)const fi=sum.inp; fo=sum.out;var n,k: longint; i, p, q: longint; s: array0..100001 of int64; a: array1..100001 of integer;BEGIN assign(input, fi); reset(input); assign(output, fo); rewrite(output); readln(n,k); s0:= 0; for i:= 1 to n do begin read(ai); si:= si1+ ai; end; for i:= 1 to k do begin readln(p, q); writeln(sq sp1); end; close(input); close(output);END.2. Dãy con liên tục có tổng có tổng bằng kconst fi=daycontongs.inp; fo=daycontongs.out;var n,k,i,j,x,max,i0,j0:longint; timthay:boolean; a:array1..100001of longint; s:array0..100001of int64;procedure docdl; begin assign(input,fi); reset(input); assign(output,fo); rewrite(output); readln(n,k); for i:=1 to n do read(ai); end;procedure dongtep; begin close(input); close(output); end;procedure xuli; begin timthay:=false; max:=0; s0:=0; for i:=1 to n do si:=si1+ai; for i:=1 to n1 do for j:=i to n do if sjsi1=k then begin timthay:=true; if ji+1> max then begin max:=ji+1; i0:=i; j0:=j; end; end; if timthay=true then for x:=i0 to j0 do write(ax, ); if timthay=false then write(ko co); end;BEGINdocdl;xuli;dongtep;END.3. Viết chương trình nhập số nguyên K ( K > 1), và N số nguyên (N >= 1). Đưa ra màn hình độ dài đoạn lớn nhất các phần tử liên tiếp nhau cùng chia hết cho K.const fi=dctdnK.inp; fo=dctdnK.out;var a,f:array1..10000000 of longint; max,i,n,k:longint;procedure docdl; begin assign(input,fi); reset(input); assign(output,fo); rewrite(output); read(n,k); for i:=1 to n do read(ai); end;procedure dongtep; begin close(input); close(output); end;procedure xuli; begin for i:=1 to n do fi:=0; for i:=1 to n do if ai mod k=0 then fi:=fi1+1 else fi:=0; max:=f1; for i:=2 to n do if fi>max then max:=fi; write(max); end;BEGINdocdl;xuli;dongtep;END.4 dãy con các phần tử liên tiếp Cx, …, Cy có tổng dương dài nhất:Cho một dãy số nguyên có n phần tử:C1, …, Cn (n 1000, |Ci| 1000).Tìm một dãy con các phần tử liên tiếp Cx, …, Cy có tổng dương dài nhất:Cx + … + Cy > 0,(y – x + 1) max. Dữ liệu vào: trong tập tin BAI1.INP gồm n + 1 dòng: + Dòng thứ nhất ghi số n; + n dòng tiếp theo ghi n số: C1, …, Cn. Kết quả: ghi ra tập tin BAI1.OUT, gồm 3 dòng: + Dòng thứ nhất ghi độ dài lớn nhất của dãy con; + Dòng thứ hai ghi chỉ số đầu của dãy con (nếu không có thì ghi 0); + Dòng thứ ba ghi chỉ số cuối của dãy con (nếu không có thì ghi 0).Ví dụ:BAI1.INPBAI1.OUT74221532151 DẠNG 2: DÃY CON KHÔNG LIÊN TỤC4. Dãy con không liên tục tăng dài nhấtCho một dãy số nguyên gồm N phần tử A1, A2, ... AN. Biết rằng dãy con tăng đơn điệu là 1 dãy Ai1,... Aik thỏa mãn i1 < i2 < ... < ik và Ai1 < Ai2 < .. < Aik. Hãy cho biết dãy con tăng đơn điệu dài nhất của dãy này có bao nhiêu phần tử? Dữ liệu: Vào từ file văn bản LIQ.INP gồm•Dòng 1 gồm 1 số nguyên là số N (1 ≤ N ≤ 1000). •Dòng thứ 2 ghi N số nguyên A1, A2, .. AN (1 ≤ Ai ≤ 10000). Kết quả: Ghi ra file LIQ.OUT độ dài của dãy con tăng đơn điệu dài nhất.Ví dụ:LIQ.INPLIQ.OUT61 2 5 4 6 24I123456Ai125462Fi1 (0)2 (0)3 (0)34 (0)2t012231Thuật toán:+ Gọi fi là độ dài dãy con đơn điệu tăng mà có phần tử ai là phần tử cuối cùng+ Nhận thấy f1 = 1;+ Công thức quy hoạch động fi = max(fj) + 1 nếu ajmax then max:=f[i]; write(max); end; BEGIN docdl; xuli; dongtep; END dãy phần tử liên tiếp Cx, …, Cy có tổng dương dài nhất: Cho dãy số nguyên có n phần tử: C1, …, Cn (n �1000, |Ci| �1000) Tìm dãy phần tử liên tiếp C x, …, Cy có tổng dương dài nhất: Cx + … + Cy > 0, (y – x + 1) max - Dữ liệu vào: tập tin BAI1.INP gồm n + dòng: + Dòng thứ ghi số n; + n dòng ghi n số: C1, …, Cn - Kết quả: ghi tập tin BAI1.OUT, gồm dòng: + Dòng thứ ghi độ dài lớn dãy con; + Dòng thứ hai ghi số đầu dãy (nếu khơng có ghi 0); + Dòng thứ ba ghi số cuối dãy (nếu khơng có ghi 0) Ví dụ: BAI1.INP BAI1.OUT -2 -3 -5 const fi='dctd.inp'; fo='dctd.out'; nmax=round(2e7); var n,i,j,max,dodai,i0,j0:longint; a,s:array[0 nmax]of longint; procedure docdl; begin assign(input,fi); reset(input); assign(output,fo); rewrite(output); readln(n); for i:=1 to n read(a[i]); end; procedure dongtep; begin close(input); close(output); end; procedure xuli; begin fillchar(s,sizeof(s),0); for i:=1 to n s[i]:=s[i-1]+a[i]; max:=0; for i:=1 to n for j:=i to n begin dodai:=j-i+1; if (s[j]-s[i-1]>0) and (dodai>max) then begin i0:=i; j0:=j; max:=dodai; end; end; writeln(max); for i:=i0 to j0 write(a[i],' '); end; BEGIN docdl; xuli; dongtep; END dãy liên tục tăng nghiêm ngặt dài VD: 10 12 29 6 output: 29 chuong trinh Var f,A: array[1 100] of integer; N,i,max:integer; Begin write('Nhap vao N:'); Readln(N); For i:=1 to n Begin write('A[',i,']='); readln(A[i]); End; For i:=1 to n f[i]:=1; max:=1; for i:=2 to n if a[i]>a[i-1] then Begin f[i]:=f[i-1]+1; if f[i]>f[max] then max:=i; end; Writeln('Day bat dau tu: ',max-f[max]+1,'co ',f[max], ' phan tu'); Readln End (chú ý: xem lại chương trình chưa) Dãy Fibonacci liên tiếp dài Cho dãy số nguyên a1, a2, , an (n = a[i-1] a[i] thuộc dãy Uk Ngược lại f[i] = a[i] thuộc dãy Uk Ngược lại f[i] = a[i] không thuộc dãy Uk + Kết toán max(f[i]) Code tham khảo: const fi='';//'QBMSEQ.INP'; fo='';//'QBMSEQ.OUT'; nmax=10000; amax=100000000; var a,f:array[0 nmax] of longint; n,i,max:longint; kt:array[1 amax] of 1; t:longint; procedure enter; begin assign(input,fi);reset(input); readln(n); for i:=1 to n readln(a[i]); a[0]:=0; close(input); fillchar(kt,sizeof(kt),0); kt[1]:=1; t:=1;i:=1; while tamax then break; kt[t]:=1; end; end; procedure solve; begin f[0]:=0; for i:=1 to n begin if kt[a[i]]=1 then if a[i]>=a[i-1] then f[i]:=f[i-1]+1 else f[i]:=1 else f[i]:=0; if f[i]>max then max:=f[i]; end; end; procedure solution; begin assign(output,fo);rewrite(output); writeln(max); close(output); end; BEGIN max:=0; enter; solve; solution; END Đoạn không lặp liên tục dài const fi='doanconkhonglap.inp'; fo='doanconkhonglap.out'; nmax=round(2e7); var n,k,i,j,max,dem:longint; a,f:array[0 nmax]of longint; kt:array[0 nmax]of boolean; procedure docdl; begin assign(input,fi); reset(input); assign(output,fo); rewrite(output); readln(n); for i:=1 to n read(a[i]); end; procedure dongtep; begin close(input); close(output); end; procedure xuli; var ok:boolean; begin dem:=0; for i:=1 to n f[i]:=1; for i:=1 to n-1 begin ok:=true; fillchar(kt,sizeof(kt),true); kt[a[i]]:=false; j:=i+1; while(j