公式
E - Climbing Silver 解説 by en_translator
We will perform a Dynamic Programming (DP) to solve this problem.
Consider performing a DP defined as \(dp[i][j] = \{1\) if Takahashi can advance to \((i,j)\), and \(0\) otherwise\(\}\).
Initialize as \(dp[i][j]=0\) for all \(i\) and \(j\).
Since \((i,C)\) is reachable for all \(i\), set \(dp[i][C]=1\).
Then, update the DP table as follows:
- For \(i=N-1,N-2,\dots,1\), perform the following.
- For \(j=1,2,\dots,N\), update \(dp[i][j]\) as follows.
- If any of \(dp[i+1][j-1],dp[i+1][j],dp[i+1][j+1]\) is \(1\), cell \((i,j)\) is reachable if we ignore the wall-cell condition. We will only consider this case.
- If \(dp[i][j]=1\) at this point, cell \((i,j)\) is already reachable, so no further investigation is needed.
- If \((i,j)\) is an empty cell, it is reachable, so set \(dp[i][j]=1\).
- If \((i,j)\) is a wall cell, if cell \((k,j)\) is an empty cell for all \(i < k \le N\), then \((i,j)\) and all cells above in the \(j\)-th column are reachable, so set \(dp[k][j]=1\) for all \(1 \le k \le i\). Whether the condition holds can be examined by precomputing the lowermost wall cell in each \(j\)-th row.
- For \(j=1,2,\dots,N\), update \(dp[i][j]\) as follows.
This solution runs in \(O(N^2)\) time.
Sample code (C++):
#include<bits/stdc++.h>
using namespace std;
int main(){
int t;
cin >> t;
while(t--){
int n,c;
cin >> n >> c;
c--;
vector<string> s(n);
vector<int> low(n,-1);
for(int i=0;i<n;i++){
cin >> s[i];
for(int j=0;j<n;j++){
if(s[i][j]=='#'){ low[j]=i; }
}
}
vector<vector<int>> dp(n,vector<int>(n,0));
for(int i=0;i<n;i++){dp[i][c]=1;}
for(int i=n-2;i>=0;i--){
for(int j=0;j<n;j++){
if(dp[i][j]>0){continue;}
bool ok=false;
if(dp[i+1][j]>0){ok=true;}
if(j>0 && dp[i+1][j-1]>0){ok=true;}
if(j+1<n && dp[i+1][j+1]>0){ok=true;}
if(ok){
if(s[i][j]=='.'){
dp[i][j]=1;
}
else{
if(low[j]==i){
for(int k=0;k<=i;k++){
dp[k][j]=1;
}
}
}
}
}
}
for(auto &nx : dp[0]){cout << nx;}
cout << "\n";
}
return 0;
}
投稿日時:
最終更新: