以d[ i ][ j ][ k ][ p ] 对应每一堆取到第几个糖果
有一个地方需要声明的是以d[ i ][ j ][ k ][ p ] 对应每一堆取到第几个糖果,那么与该状态对应的篮子的状态一定只有一个,这是这样动态规划的原因;
#include <cstring> #include <cstdio> #include <vector> #include <iostream> #include <algorithm> using namespace std; const int maxn = 45; int d[maxn][maxn][maxn][maxn]; int s,n; int st[5][maxn]; bool vis[maxn][maxn][maxn][maxn]; int dp(int t[],int s,int bask[]){ if(vis[t[1]][t[2] ][t[3] ][t[4]]) return d[t[1]][t[2] ][t[3] ][t[4]]; vis[t[1]][t[2] ][t[3] ][t[4]] = true; if(s==5) return d[t[1]][t[2] ][t[3] ][t[4]]=0; int& ans = d[t[1]][t[2] ][t[3] ][t[4]]; ans=0; for(int i=1;i<=4;i++){ if(t[i] <= n){ int nt[7]; int nbask[25]; memcpy(nt,t,sizeof(nt)); memcpy(nbask,bask,sizeof(nbask)); if(bask[st[i][t[i]]]){ nbask[st[i][t[i]]] = 0; nt[i]+=1; ans=max(ans,dp(nt,s-1,nbask)+1); } else { nbask[st[i][t[i]]] = 1; nt[i]+=1; ans=max(ans,dp(nt,s+1,nbask)); } } } return ans; } int main() { while(scanf("%d",&n)==1&&n){ for(int j=1;j<=n;j++) for(int i=1;i<=4;i++) scanf("%d",&st[i][j]); int top[7],bask[25]; memset(bask,0,sizeof(bask)); memset(vis,false,sizeof(vis)); for(int i=1;i<=4;i++) top[i]=1; printf("%d\n",dp(top,0,bask)); } return 0; }