CoderForces 280B(记忆化搜索)
题目大意:一个纸牌游戏,52张纸牌排成一列,每张纸牌有面值和花色两种属性。每次操作可以用最后一张纸牌将倒数第二张或者倒数第四张替换,但前提是两张牌的花色或者面值相同。问最终能否只剩一张牌。
题目分析:取当前所剩纸牌张数和最后三张牌作为状态,显然深搜要超时。记忆化搜索即可。
代码如下:
# include<iostream> # include<string> # include<cstdio> # include<cstring> # include<algorithm> using namespace std; int n; string p[55]; bool f[55][55]; bool dp[55][55][55][55]; bool dfs(int left,int ppre,int pre,int lst) { if(dp[left][ppre][pre][lst]) return false; if(left==2&&f[lst][pre]) return true; if(left==3&&f[lst][pre]&&f[lst][ppre]) return true; if(left>3&&f[lst][left-4]&&dfs(left-1,lst,ppre,pre)) return true; if(left>3&&f[lst][pre]&&dfs(left-1,left-4,ppre,lst)) return true; dp[left][ppre][pre][lst]=true; return false; } int main() { while(~scanf("%d",&n)) { for(int i=0;i<n;++i) cin>>p[i]; memset(f,false,sizeof(f)); memset(dp,false,sizeof(dp)); for(int i=0;i<n;++i) for(int j=0;j<n;++j) if(p[i][0]==p[j][0]||p[i][1]==p[j][1]) f[i][j]=true; if(n==1||dfs(n,n-3,n-2,n-1)) printf("YES\n"); else printf("NO\n"); } return 0; }