Vấn đề 1: trò chơi Video combo [Neal Wu, 2012]Bessie đang chơi một trò chơi video! Trong game, ba chữ cái 'A', 'B' và 'C' có các nút chỉ có giá trị. Bessie có thể bấm các nút trong bất kỳ thứ tự nào cô thích; Tuy nhiên, có những chỉ N combo khác biệt có thể (1 < = N < = 20). Combo tôi đại diện như là một chuỗi S_i có chiều dài từ 1 đến 15 và chứa chỉ các ký tự 'A', 'B' và 'C'.Bất cứ khi nào Bessie ép một sự kết hợp của các chữ cái phù hợp với với một combo, cô được một trong những điểm cho các kết hợp. Combo có thể trùng với nhau hoặc thậm chí hoàn thành cùng một lúc! Ví dụ: nếu N = 3 và ba thể combo "ABA", "CB" và "ABACB", và Bessie ép "ABACB", cô ấy sẽ kết thúc với 3 điểm. Bessie có thể điểm số điểm cho một combo đơn nhiều hơn một lần.Bessie tất nhiên muốn để kiếm được điểm càng nhanh càng tốt. Nếu shepresses chính xác K nút (1 < = K < = 1.000), số lượng điểm cô có thể kiếm được tối đa là gì?Vấn ĐỀ TÊN: comboĐỊNH DẠNG ĐẦU VÀO:* Dòng 1: Ngăn cách không gian hai số nguyên: N và K.* Dòng 2..N + 1: dòng i + 1 có chứa chỉ là chuỗi S_i, đại diện cho combo tôi.MẪU các đầu VÀO (file combos.in):3 7ABACBABACBĐỊNH DẠNG ĐẦU RA:* Dòng 1: Một số nguyên đơn, số điểm Bessie, tối đa có thể có được.MẪU đầu RA (file combos.out):4ĐẦU RA THÔNG TIN CHI TIẾT:Trình tự tối ưu của các nút trong trường hợp này là ABACBCB, trong đó cung cấp cho 4điểm--1 từ ABA, 1 từ ABACB và 2 từ CB. Giải phápGiải pháp các ghi chú (Richard Peng): Một giải pháp rõ ràng đầu tiên sẽ là một trong những cố gắng tất cả các chuỗi 3K của chiều dài K. xem xét sửa đổi nhỏ nhỏ sau đây của nó: thay vì đếm số lượng các điểm cuối, khi chúng tôi liệt kê các ký tự tại i, chúng tôi đếm số lượng các điểm thu được bằng cách combo kết thúc ở vị trí tôi.Sau đó, vì các combo có chiều dài nhất L ≤ 15, chúng tôi chỉ cần theo dõi cuối 15 ký tự trong trình tự. Do đó nhà nước của các giá trị 15 trước trong tiến trình duy nhất xác định bang liệt kê của chúng tôi, cho một thuật toán thời gian O(3LLNK).Tuy nhiên, lưu ý rằng chúng tôi có thể làm tốt hơn. Giả sử chúng ta đang ở vị trí tôi và có một số vị trí j < tôi như vậy mà các chuỗi ký tự giữa các vị trí j và tôi không phải là một xâu con của bất kỳ combo. Sau đó có thể không có bất kỳ kết hợp bắt đầu trước khi vị trí j kết thúc ở vị trí sau khi tôi.Hence, we only need to track the part of the sequence that's a substring of one of the combos. More precisely, we identify the earliest j, or the longest suffix of the sequence so far that's a substring of some combo. Since there are only O(NL2) possible substrings of one of the combos, this immediately brings the number of states to something manageable. Since each state only be modified by adding one of 3 characters (A, B, C) to it, the transitions to position i + 1 can also be precomputed in O(N2L4) time naively. In total this gives a O(N2L4 + NL2K) algorithm, which is sufficient for full points. Note however a key detail is that multiple combos can end at position i, making it necessary to precompute a score for each state as well.Several further improvements are possible, with the most immediate being that instead of considering substrings of combos, we consider only prefixes. This is because if a combo ends after i, it must have started somewhere earlier. Once again, special care is needed to ensure that the state tracks the longest suffix that's a prefix of some combo. This gives a O(N2L2+NLK) time algorithm.Here is an implementation of a slightly different algorithm from problem author Neal Wu, in which he considers only states where one of the combos is matched exactly at position i, with a bit more work done computing transitions.#include #include #include #include using namespace std;FILE *input = fopen ("combos.in", "r"), *output = fopen ("combos.out", "w");const int N_MAX = 105, LEN_MAX = 105, K_MAX = 1005;int N, K, combo_len[N_MAX];char combos[N_MAX][LEN_MAX];int contains[N_MAX][LEN_MAX], attach[N_MAX][N_MAX];int dp[K_MAX][N_MAX];bool match(int a, int b, int offset){ int a_len = combo_len[a], b_len = combo_len[b]; assert(offset <= b_len && b_len - offset <= a_len); int a_start = a_len - (b_len - offset); return strncmp(combos[a] + a_start, combos[b], b_len - offset) == 0;}int main(){ fscanf(input, "%d %d", &N, &K); for (int i = 0; i < N; i++) { fscanf(input, "%s", combos[i]); combo_len[i] = strlen(combos[i]); } memset(contains, 0, sizeof(contains)); for (int i = 0; i < N; i++) { contains[i][0] = 0; for (int end = combo_len[i], offset = 0; end >= 0; end--, offset++) { int occur = 0; for (int j = 0; j < N; j++) if (end >= combo_len[j] && strncmp(combos[i] + end - combo_len[j], combos[j], combo_len[j]) == 0) occur++; conta
đang được dịch, vui lòng đợi..