Submission #1293915

#TimeUsernameProblemLanguageResultExecution timeMemory
1293915saidshikhovKangaroo (CEOI16_kangaroo)C++20
0 / 100
0 ms332 KiB
#include <iostream>
#include <vector>
#include <cstring>
using namespace std;

const int MOD = 1000000007;

int main() {
    int N, cs, cf;
    cin >> N >> cs >> cf;
    
    // dp[l][r] = количество способов посетить все клетки от l до r
    // l - левая граница посещенного непрерывного отрезка
    // r - правая граница посещенного непрерывного отрезка
    vector<vector<int>> dp(N + 2, vector<int>(N + 2, 0));
    
    // Инициализация: начинаем с начальной клетки
    // Мы можем пойти как влево, так и вправо
    if (cs == cf) {
        // Если начальная и конечная совпадают - только если N=1, но по условию N>=2 и cs != cf
        cout << 0 << endl;
        return 0;
    }
    
    // Начинаем с отрезка [cs, cs]
    dp[cs][cs] = 1;
    
    // Будем расширять отрезок
    for (int len = 1; len <= N; len++) {
        for (int l = 1; l <= N; l++) {
            int r = l + len - 1;
            if (r > N) continue;
            
            if (dp[l][r] == 0) continue;
            
            // Расширяем влево
            if (l > 1) {
                // Проверяем условие смены направления
                // Если последний прыжок был направо, то следующий должен быть налево
                // Это выполняется автоматически при расширении влево
                dp[l - 1][r] = (dp[l - 1][r] + dp[l][r]) % MOD;
            }
            
            // Расширяем вправо
            if (r < N) {
                // Проверяем условие смены направления  
                // Если последний прыжок был налево, то следующий должен быть направо
                // Это выполняется автоматически при расширении вправо
                dp[l][r + 1] = (dp[l][r + 1] + dp[l][r]) % MOD;
            }
        }
    }
    
    // Ответ - количество способов, когда весь отрезок [1, N] посещен
    // и последняя клетка - cf
    // Но нам нужно убедиться, что маршрут заканчивается в cf
    
    // Альтернативный подход: ДП с учетом направления
    vector<vector<int>> dp_left(N + 2, vector<int>(N + 2, 0));
    vector<vector<int>> dp_right(N + 2, vector<int>(N + 2, 0));
    
    // Инициализация
    if (cs < cf) {
        dp_right[cs][cs] = 1; // начинаем, идя направо
    } else {
        dp_left[cs][cs] = 1; // начинаем, идя налево
    }
    
    for (int len = 1; len <= N; len++) {
        for (int l = 1; l <= N; l++) {
            for (int r = l; r <= N; r++) {
                if (r - l + 1 != len) continue;
                
                // Расширяем влево из состояния "направо"
                if (l > 1 && dp_right[l][r] > 0) {
                    dp_left[l - 1][r] = (dp_left[l - 1][r] + dp_right[l][r]) % MOD;
                }
                
                // Расширяем вправо из состояния "налево"  
                if (r < N && dp_left[l][r] > 0) {
                    dp_right[l][r + 1] = (dp_right[l][r + 1] + dp_left[l][r]) % MOD;
                }
                
                // Также расширяем влево из состояния "налево" (меняем направление)
                if (l > 1 && dp_left[l][r] > 0) {
                    dp_right[l - 1][r] = (dp_right[l - 1][r] + dp_left[l][r]) % MOD;
                }
                
                // Расширяем вправо из состояния "направо" (меняем направление)
                if (r < N && dp_right[l][r] > 0) {
                    dp_left[l][r + 1] = (dp_left[l][r + 1] + dp_right[l][r]) % MOD;
                }
            }
        }
    }
    
    // Ответ: сумма способов закончить в cf
    int answer = 0;
    for (int l = 1; l <= cf; l++) {
        for (int r = cf; r <= N; r++) {
            if (l <= cf && cf <= r) {
                answer = (answer + dp_left[l][r]) % MOD;
                answer = (answer + dp_right[l][r]) % MOD;
            }
        }
    }
    
    cout << answer << endl;
    
    return 0;
}

#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...