题目链接:https://vjudge.net/contest/363945
解题思路:此题状态很容易想到,但是我的记忆化搜索真的很菜,写完之后改了好久,问题主要出在递归上,我不知道该怎么表示了。由于记忆化搜索理解的不好,所以弄了好长时间才AC了。
AC代码
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #include<cmath> #include<map> #include<set> #include<stack> #include<queue> #include<vector> #include<string> #define cla(a, sum) memset(a, sum, sizeof(a)) #define rap(i,m,n) for(i=m;i<=n;i++) #define rep(i,m,n) for(i=m;i>=n;i--) using namespace std; typedef long long ll; typedef pair<ll,ll>P; const int Inf=0x3f3f3f3f; const double eps=1e-8; const int maxn=6e3+5; int n; int dp[45][45][45][45]; int a[45][5],vis[25]; int top[5]; int dfs(int k) { if(dp[top[1]][top[2]][top[3]][top[4]]!=-1) return dp[top[1]][top[2]][top[3]][top[4]]; if(k==5)return dp[top[1]][top[2]][top[3]][top[4]]=0; int i,j; int ans=0; rap(i,1,4){ if(top[i]>n)continue; if(vis[a[top[i]][i]]){ vis[a[top[i]][i]]=0; top[i]++; ans=max(ans,1+dfs(k-1)); top[i]--; vis[a[top[i]][i]]=1; } else{ vis[a[top[i]][i]]=1; top[i]++; ans=max(ans,dfs(k+1)); top[i]--; vis[a[top[i]][i]]=0; } } dp[top[1]][top[2]][top[3]][top[4]]=ans; return ans; } int main() { while(scanf("%d",&n)&&n) { int i,j,k; rap(i,1,n){ rap(j,1,4){ scanf("%d",&a[i][j]); } } cla(dp,-1);cla(vis,0); rap(i,0,4)top[i]=1; dfs(0); cout<<dp[1][1][1][1]<<endl; } return 0; }