P1002 [NOIP2002 普及組] 過河卒

_Yxc發表於2024-04-08

題意:卒子過河,有個馬,問安全到達終點的路徑有多少條。起點在0,0。每一步可以往右或者往下。

思路:處理出馬的看守點,然後暴力。。看了一下暴力會TLE。400^2. 直接dp轉移即可。

總結:不知道這個還要開long long, 哎。!

void solve(){
    pair<int, int> destination;
    vector<pair<int, int>> hourse(1);
    cin >>destination.first >> destination.second;
    cin >> hourse[0].first >> hourse[0].second;

    hourse.emplace_back(hourse[0].first - 1, hourse[0].second - 2);
    hourse.emplace_back(hourse[0].first - 1, hourse[0].second + 2);
    hourse.emplace_back(hourse[0].first + 1, hourse[0].second - 2);
    hourse.emplace_back(hourse[0].first + 1, hourse[0].second + 2);

    hourse.emplace_back(hourse[0].first + 2, hourse[0].second - 1);
    hourse.emplace_back(hourse[0].first - 2, hourse[0].second - 1);
    hourse.emplace_back(hourse[0].first + 2, hourse[0].second + 1);
    hourse.emplace_back(hourse[0].first - 2, hourse[0].second + 1);

    sort(hourse.begin(), hourse.end());
    for (const auto& x : hourse){
        if (x == destination){
            cout << 0 << '\n';
            return;
        }
    }

    vector<vector<long long>>dp(22, vector<long long>(22, 0));
    auto inHourse = [&](int x, int y){
      for (const auto& cur : hourse){
        if (cur == pair<int, int>{x, y}){
            return true;
        }
      }
      return false;
    };

    dp[0][0] = 1;
    for (int i = 0; i <= 20; ++i){
        for (int j = 0; j <= 20; ++j){
            if (inHourse(i, j) == false ){
                if (inHourse(i + 1, j) == false) dp[i + 1][j] += dp[i][j];
                if (inHourse(i, j + 1) == false) dp[i][j + 1] += dp[i][j];
            }
        }
    }

    cout << dp[destination.first][destination.second] << '\n';
}

相關文章