Cho một hàng gồm n (1 1, A2, …, An và số nguyên ổn dương k (k Dòng 1: Chẹn số nDòng 2: Chứa hẹn n số A1, A2, …, An cách nhau tối thiểu một vệt cách
Dòng 1: Ghi độ lâu năm hàng con tìm đượcCác cái tiếp: Ghi những phần tử được lựa chọn vào hàng conDòng cuối: Ghi tổng các bộ phận của hàng bé kia.
Bạn đang xem: Dãy con dài nhất có tổng chia hết cho k
SUBSEQ.INP | SUBSEQ.OUT |
10 5 | 8 |
1 6 11 5 10 15 trăng tròn 2 4 9 | a<10> = 9 |
a<9> = 4 | |
a<7> = 20 | |
a<6> = 15 | |
a<5> = 10 | |
a<4> = 5 | |
a<3> = 11 | |
a<2> = 6 | |
Sum = 80 |
3.4.1. Cách giải 1
Đề bài xích thưởng thức chọn ra một số tối đa các phần tử trong dãy A và để được một hàng bao gồm tổng phân chia hết mang đến k, ta rất có thể giải bài xích toán thù bằng cách thức coi ngó tổ hợp bởi xoay lui gồm nhận xét nhánh cận nhằm giảm bớt ngân sách vào nghệ thuật vét cạn. Dưới đây ta trình bày cách thức quy hoạch động:
Nhận xét 1: Không tác động mang lại kết quả ở đầu cuối, ta rất có thể đặt: Ai := Ai mod k với tất cả i: 1 i1, Ai2, …, Aim. Các phần tử này có tổng đồng dư với S theo mô-đun k.
Xét các dãy sau:
Dãy 0 := () = Dãy rỗng (Tổng = 0 (thủ thuật k))
Dãy 1 := (Ai1) Dãy 2 := (Ai1, Ai2)
Dãy 3 := (Ai1, Ai2, Ai3)
… …
Dãy m := (Ai1, Ai2, …, Aim)
bởi thế có m + 1 hàng, giả dụ m >= k thì theo nguyên lý Dirichlet vẫn sống thọ nhì dãy có tổng đồng dư theo mô-đun k. Giả sử đó là nhì dãy:
Ai1 + Ai2 + … + Aip = Ai1 + Ai2 + … + Aip + Aip+1 + … + Aiq (gian lận k)
Suy ra Aip+1 + … + Aiq phân chia hết mang lại k. Vậy ta rất có thể xoá không còn các thành phần này vào hàng vẫn chọn mà vẫn được một dãy có tổng đồng dư với S theo modul k, mâu thuẫn cùng với giả thiết là hàng đang lựa chọn có số bộ phận buổi tối tgọi.
Công thức truy vấn hồi:
Nếu ta Hotline F là số phần tử tối tgọi buộc phải chọn vào dãy A1, A2, …, Ai để sở hữu tổng phân chia k dư t. Nếu không tồn tại phương pháp lựa chọn ta coi F =
Nếu vào dãy bên trên chưa phải lựa chọn Ai thì F = F;
Nếu trong dãy bên trên bắt buộc lựa chọn Ai thì F = 1 + F


Xem thêm: Jebrains Resharper 2021 - Jebrains Resharper Ultimate
Từ trên suy ra F = min (F, 1 + F).
Còn tất nhiên, cơ sở quy hoạch động: F(0, 0) = 0; F(0, i) =

3.4.2. Cách giải 2
Phân các thành phần vào dãy a theo những lớp đồng dư modul k. Lớp i có những phần tử phân chia k dư i. call Count là số lượng các thành phần trực thuộc lớp i.Với 0 = 1; 0 const InputFile = 'SUBSEQ.INP'; OutputFile = 'SUBSEQ.OUT'; maxN = 1000; maxK = 50;var a: array<1..maxN> of Integer; Count: array<0..maxK - 1> of Integer; f, Trace: array<0..maxK - 1, 0..maxK - 1> of Integer; n, k: Integer;procedure Enter;var fi: Text; i: Integer;begin Assign(fi, InputFile); Reset(fi); ReadLn(fi, n, k); FillChar(Count, SizeOf(Count), 0); for i := 1 to lớn n vì chưng begin Read(fi, a); Inc(Count thủ thuật k>); Nhập tài liệu đồng thời với bài toán tính những Count<.> end; Close(fi);end;function Sub(x, y: Integer): Integer;var tmp: Integer;begin tmp := (x - y) gian lận k; if tmp >= 0 then Sub := tmp else Sub := tmp + k;end;procedure Optimize;var i, j, t: Integer;begin FillChar(f, SizeOf(f), 0); f<0, 0> := Count<0>; FillChar(Trace, SizeOf(Trace), $FF); Khởi tạo thành các mảng Trace=-1 Trace<0, 0> := Count<0>; Ngoại trừ Trace<0, 0> = Count<0> for i := 1 to k - 1 vị for t := 0 to k - 1 bởi for j := 0 khổng lồ Count vì if (Trace -1) and (f f + j) then begin f := f + j; Trace := j; end;end;procedure Result;var fo: Text; i, t, j: Integer; Sum: LongInt;begin t := 0; Tính lại những Count := Số phần tử phương án tối ưu đã chọn vào lớp i for i := k - 1 downkhổng lồ 0 vì chưng begin j := Trace; t := Sub(t, j * i); Count := j; end; Assign(fo, OutputFile); Rewrite(fo); WriteLn(fo, f