Codeforces Round #325D (Div. 2) (DP)
题目链接:
分析:dp
我们先初始化,dp[i]表示当前列第i行是否可达,r[i]表示上一个dp值,接下来从头搜到尾
如果该位置满足s[i+1]=='.'且i<n,则用r[i]更新该位置的上面和下面一行,所以这是为什么数组开dp[5],r[5],
再判断该位置的i+2*k,i+2*k+1,i+2*k+2是否都是'.',表示没有火车,处于安全位置
最后判断dp[1],dp[2],dp[3]是否可达,一个可达即输出yes
详情见代码
1 #include<cstdio> 2 #include<cstring> 3 4 int t,n,k,dp[5],r[5]; 5 char s[4][101]; 6 bool check(int x,int y){ return x < n && (s[y][x] != '.');} 7 int max(int a,int b){ return a > b ? a : b; } 8 int main() 9 { 10 for(scanf("%d",&t); t--; ) 11 { 12 scanf("%d %d",&n,&k); 13 for(int i = 1; i <= 3; ++i) 14 { 15 scanf("%s",s[i]); 16 r[i] = dp[i] = (s[i][0] == 's') && (s[i][1] == '.'); 17 } 18 for(int k = 0,i = 1; i < n; ++i,++k) 19 { 20 for(int j = 1; j <= 3; ++j) if(!check(i+2*k,j)) 21 { 22 dp[j-1] = max(dp[j-1],r[j]); 23 dp[j+1] = max(dp[j+1],r[j]); 24 } 25 for(int j = 1; j <= 3; ++j) {if(check(i+2*k,j) || check(i+2*k+1,j) || check(i+2*k+2,j)) dp[j] = 0;r[j] = dp[j];} 26 } 27 if(dp[1] || dp[2] || dp[3]) puts("YES");else puts("NO"); 28 } 29 return 0; 30 }
一直地一直地往前走