# Dynamic Programming# Greedy# Recursion# Array

j122 - 11957 - Checkers

🔗 前往 ZeroJudge 原題

題目描述

題目給定一個 n x n 的棋盤,棋盤上包含白子 (W)、黑子 (B) 和空位 (.)。目標是計算白子移動到棋盤最上方一列的所有可能路徑數量。白子只能沿對角線方向移動,即 (x, y) 可以移動到 (x+1, y+1) 或 (x-1, y+1)。如果目標位置有黑子,白子可以跳過它,移動到 (x+2, y+2) 或 (x-2, y+2)。答案需要取模 1000007。

解題思路

這題可以使用動態規劃來解決。dp[i][j] 表示從位置 (i, j) 到最上方一列的可能路徑數量。從棋盤的底部往上遍歷,如果當前位置是白子,則計算從該位置到上方兩格的可能路徑數量,並將其加到上方兩格的 dp 值中。需要考慮跳過黑子的情況。

複雜度分析

  • 時間複雜度: O(n^2)
  • 空間複雜度: O(n^2)

程式碼

#include <bits/stdc++.h>
using namespace std;
long long n,t,dp[105][105],ans,mod=1000007;
char c;
int main(){
	cin.tie(0); ios::sync_with_stdio(false);
	cin >> t;
	for(int ca=1;ca<=t;++ca){
		ans=0;
		memset(dp,0,sizeof(dp));
		cin >> n;
		for(int i=1;i<=n;++i)
			for(int j=1;j<=n;++j){
				cin >> c;
				if(c=='W')
					dp[i][j]=1;
				else if(c=='B')
					dp[i][j]=-1;
			}
		for(int i=n;i>=1;--i){
			for(int j=1;j<=n;++j){
				if(dp[i][j]>0){
					dp[i][j]%=mod;
					if(i==1)
						ans+=dp[i][j];
					else{
						if(dp[i-1][j+1]!=-1)
							dp[i-1][j+1]+=dp[i][j];
						else if(i>1&&j<n&&dp[i-1][j+1]==-1&&dp[i-2][j+2]!=-1)
							dp[i-2][j+2]+=dp[i][j];
						if(dp[i-1][j-1]!=-1)
							dp[i-1][j-1]+=dp[i][j];
						else if(i>1&&j>1&&dp[i-1][j-1]==-1&&dp[i-2][j-2]!=-1)
							dp[i-2][j-2]+=dp[i][j];
					}
				}
			}
		}
		cout << "Case " << ca << ": " << ans%mod << "\n";
	}
}

Discussion