LH Quảng cáo: lazijsc@gmail.com

Bài tập  /  Bài đang cần trả lời

Dãy còn ít nhất 3 phần tử

Cho dãy gồm n số nguyên a1, a2,…, an (1 ≤ ai ≤ 3, I = 1 g n). Có bao nhiêu cách để xóa đi một số phần tử của dãy (không xóa phần tử nào cũng được cọi là một cách) mà vẫn giữ nguyên thứ tự ban đầu để được một dãy mới thỏa mãn hai yêu cầu sau:

  1. Dãy còn ít nhất 3 phần tử.
  2. Phần tử đầu tiên của dãy có giá trị 1, tiếp theo là một số phần tử có giá trị là 2 (ít nhất có 1 số 2) và kết thúc bằng đúng một phần tử có giá trị là 3.

VD: các dãy {1, 2, 2, 3} và dãy {1, 2, 3} thỏa mãn yêu cầu; các dãy {1, 2, 3, 3} và dãy {1, 1, 2, 3} không thỏa mãn yêu cầu.

Dữ lIệu:

+ Dòng 1: số nguyên dương n (n ≤ 106) là số lượng phần tử của dãy.

+ Dòng 2: ghi n số nguyên a1, a2,…, an là giá trị của các phần tử của dãy ban đầu

Kết quả: Gồm một dòng duy nhất là số cách xóa để được dãy mới thỏa mãn yêu cầu của đề bài. Do số lượng cách xóa phần tử có thể rất lớn nên bạn chỉ cần ghi ra số lượng cách xóa sau khi chia lấy dư cho (109 + 7)

Ví dụ: 

INP
 

8

1 2 1 2 3 1 2 3

OUT

 

 

15

1 trả lời
Hỏi chi tiết
662
Tham khảo câu trả lời từ Trợ lý ảo Lazi
Để giải bài toán này, ta sẽ sử dụng phương pháp quy hoạch động.

Gọi dp[i] là số cách xóa để được dãy mới thỏa mãn yêu cầu của đề bài với i là chỉ số của phần tử cuối cùng trong dãy.

Ta có các trường hợp sau:
- Nếu a[i] = 1, ta không thể xóa phần tử này vì phần tử đầu tiên của dãy phải là 1. Vậy dp[i] = dp[i-1].
- Nếu a[i] = 2, ta có thể xóa phần tử này hoặc không xóa. Nếu xóa, ta sẽ có dp[i] = dp[i-1] + dp[i-2]. Nếu không xóa, ta sẽ có dp[i] = dp[i-1].
- Nếu a[i] = 3, ta chỉ có thể không xóa phần tử này. Vậy dp[i] = dp[i-1].

Với công thức trên, ta có thể tính được dp[i] cho tất cả các i từ 1 đến n.

Cuối cùng, kết quả sẽ là dp[n] với n là số lượng phần tử của dãy ban đầu.

Độ phức tạp của thuật toán này là O(n), với n là số lượng phần tử của dãy ban đầu.

Dưới đây là code Python thực hiện thuật toán trên:

```python
MOD = 10**9 + 7

n = int(input())
a = list(map(int, input().split()))

dp = [0] * (n+1)
dp[0] = 1

for i in range(1, n+1):
if a[i-1] == 1:
dp[i] = dp[i-1]
elif a[i-1] == 2:
dp[i] = (dp[i-1] + dp[i-2]) % MOD
else:
dp[i] = dp[i-1]

print(dp[n])
```

Với input là:
```
8
1 2 1 2 3 1 2 3
```

Output sẽ là:
```
15
```
5
3
Đức Anh Trần
08/10/2023 16:12:44
+5đ tặng
const
    MOD = 1000000007;

var
    n, i: longint;
    a: array[1..1000000] of longint;
    cnt1, cnt2, cnt3: array[1..1000000] of longint;
    ans: int64;

begin
    readln(n);
    for i := 1 to n do
        read(a[i]);

    // Khởi tạo giá trị ban đầu cho mảng đếm
    if a[1] = 1 then cnt1[1] := 1;
    if a[1] = 2 then cnt2[1] := 1;
    if a[1] = 3 then cnt3[1] := 1;

    // Tính toán các giá trị đếm
    for i := 2 to n do
    begin
        cnt1[i] := cnt1[i-1];
        cnt2[i] := cnt2[i-1];
        cnt3[i] := cnt3[i-1];
        if a[i] = 1 then inc(cnt1[i]);
        if a[i] = 2 then inc(cnt2[i]);
        if a[i] = 3 then inc(cnt3[i]);
    end;

    ans := 0;
    for i := 1 to n do
    begin
        if a[i] = 3 then
        begin
            ans := ans + (cnt1[i] * (cnt2[i] - cnt1[i])) mod MOD;
            ans := ans mod MOD;
        end;
    end;

    writeln(ans);
end.
 

Mở khóa để xem toàn bộ nội dung trả lời

(?)
Bạn đã đạt đến giới hạn của mình. Bằng cách Đăng ký tài khoản, bạn có thể xem toàn bộ nội dung trả lời
Cải thiện điểm số của bạn bằng cách đăng ký tài khoản Lazi.
Xem toàn bộ các câu trả lời, chat trực tiếp 1:1 với đội ngũ Gia sư Lazi bằng cách Đăng nhập tài khoản ngay bây giờ
Tôi đã có tài khoản? Đăng nhập

Bạn hỏi - Lazi trả lời

Bạn muốn biết điều gì?

GỬI CÂU HỎI
Học tập không giới hạn cùng học sinh cả nước và AI, sôi động, tích cực, trải nghiệm
Trắc nghiệm Lập trình Lớp 10 mới nhất

Hôm nay bạn thế nào? Hãy nhấp vào một lựa chọn, nếu may mắn bạn sẽ được tặng 50.000 xu từ Lazi

Vui Buồn Bình thường

Học ngoại ngữ với Flashcard

×
Trợ lý ảo Trợ lý ảo
×
Gia sư Lazi Gia sư