Hướng dẫn bài BPN - Các cặp số đẹp

Trùm CUỐI 2022-01-11 0:54:03

Link đến trang bài tập

Thuật toán:

Trước tiên chúng ta nhận xét rằng độ dài của dãy không bao giờ vượt quá 50 . Lý do là bởi vì các b_i-a_i khác nhau từng đôi một và do 0+1+2+\ldots+50 > 1000 . Vì các dãy là không giao nhau nên nếu đặt c_i=b_i-a_i+1 là độ dài của dãy thứ i ta có ∑_ic_i≤n .

Ta tính toán giá trị qui hoạch động sau: d[i][j][k] - số dãy thỏa mãn điều kiện c_1<c_2<\ldots<c_i, c_i≥1, c_1+c_2+\ldots+c_i=j và giá trị của phần tử lớn nhất bé hơn k (chặn trên của dãy). Công thức qui hoạch động dưới đây cho phép chúng ta thiết lập số cách khác nhau khi thiết lập độ dài của dãy. Nó có thể tính đơn giản như sau:

  • cơ sở d[0][0][1]=0
  • d[i][j][k+1]=d[i][j][k+1]+d[i][j][k]
  • d[i+1][j+k][k+1]=d[i+1][j+k][k+1]+d[i][j][k]

Chúng ta có thể tính toán công thức qui hoạch động trên với chi phí O(n^2) bộ nhớ (tuy nhiên nếu để mảng 3 chiều cũng chấp nhận được). Chú ý rằng sau khi tính d[i][j][k] sẽ được nhân với i! (vì ta đã giả thiết c_1<c_2<\ldots<c_i , nhưng trên thực tế nó có thể là một hoán vị bất kỳ)

Với giá trị n,k đã cho. Đặt sum[len]=∑_xd[k][len][x] với x là các cận trên có thể có.

Vấn đề tiếp theo là ta tính xem có bao nhiêu cách đặt các khoảng với tổng độ dài len vào trong đoạn độ dài n .

Đặt x_1=a_1,x_2=a_2-b_1,…,x_k=a_k-b_{k-1},x_{k+1}=n-b_k ta có phương trình x_1+x_2+\ldots+x_k+x_{k+1}=n-len (*)

Do vậy mỗi giá trị S[len] cần phải nhân với số nghiệm của phương trình (*).

Đặt f[i,j] là số nghiệm không âm của phương trình x_1+x_2+\ldots+x_i=j

Ta có thể chọn x_i=0,1,2,…,j do đó:

  • f[i,j]=f[i-1,j]+f[i-1,j-1]+\ldots + f[i-1,0]
  • f[i,j-1]=f[i-1,j-2]+f[i-1,j-3]+\ldots+f[i-1,0]$

Do vậy f[i,j]-f[i,j-1]=f[i-1,j] hay f[i,j]=f[i,j-1]+f[i-1,j]

Do vậy có thể tính mảng f trong O(n^2)

Và số nghiệm của phương trìn (*) chính là f[k+1,n-len]

Đáp số của bài toán là : ∑_{len=0}^nsum[len]×f[k+1,n-len]