题目:https://www.luogu.org/problemnew/show/P2530
dp或搜索。
dp做法就是 当前值+1 转移到 当前某一维为0、位置前进了c位 的地方。但没写。
写了搜索的方法。细节众多,而且RE地莫名其妙!
搜索要注意记忆化。
特别奇怪的细节:代码中用注释(d数组)代替t1 t2 t3的话就会WA。
子函数中传参如果写成c[ ],就是不确定大小,于是不能用memcpy了。
AC代码:
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF=1005; int n,col[105],tmp[5],f[105][15][15][15]; char ch; int num(char ch) { if(ch=='A')return 1; if(ch=='B')return 2; if(ch=='C')return 3; } int dfs(int c[5],int now) { if(f[now][c[1]][c[2]][c[3]])return f[now][c[1]][c[2]][c[3]]; if(!c[1]&&!c[2]&&!c[3])return 0; int num=INF,j=0; int t1=c[1],t2=c[2],t3=c[3]; // int d[5]={0}; // memcpy(d,c,sizeof c); // d[1]=c[1];d[2]=c[2];d[3]=c[3]; for(int i=1;i<=3;i++) { if(!c[i])continue; int t=c[i]; c[i]=0; for(j=now;j<now+t&&j<=n;j++) c[col[j]]++; num=min(num,dfs(c,j)); c[1]=t1;c[2]=t2;c[3]=t3; // memcpy(c,d,sizeof d); // c[1]=d[1];c[2]=d[2];c[3]=d[3]; } return f[now][c[1]][c[2]][c[3]]=num+1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf(" %c",&ch); col[i]=num(ch); if(i<=10)tmp[col[i]]++; } printf("%d",dfs(tmp,min(11,n+1))); return 0; }
RE+WA+MLE代码(注意判断return 0和记忆化的那两句的位置是在补满10个以后):

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF=105; int n,col[105],tmp[5],f[105][15][15][15]; char ch; int num(char ch) { if(ch=='A')return 1; if(ch=='B')return 2; if(ch=='C')return 3; } int dfs(int c[5],int now) { int k=10-c[1]-c[2]-c[3]; for(int i=now;i<now+k&&i<=n;i++) c[col[i]]++; if(!c[1]&&!c[2]&&!c[3]&&now>1)return 0; if(f[now][c[1]][c[2]][c[3]])return f[now][c[1]][c[2]][c[3]]; int d[5]={0},num=INF; // d[1]=c[1];d[2]=c[2];d[3]=c[3]; memcpy(d,c,sizeof c); for(int i=1;i<=3;i++) { if(!c[i])continue; c[i]=0; num=min(num,dfs(c,now+k)); c[i]=d[i]; } return f[now][c[1]][c[2]][c[3]]=num+1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf(" %c",&ch); col[i]=num(ch); } printf("%d",dfs(tmp,1)); return 0; }
改了改上边之后的WA代码:

#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int INF=105; int n,col[105],tmp[5],f[105][15][15][15]; char ch; int num(char ch) { if(ch=='A')return 1; if(ch=='B')return 2; if(ch=='C')return 3; } int dfs(int c[],int now,int k) { // int k=10-c[1]-c[2]-c[3],l=0; int l=0; for(l=now;l<now+k&&l<=n;l++) c[col[l]]++; if(f[now][c[1]][c[2]][c[3]])return f[now][c[1]][c[2]][c[3]]; if(!c[1]&&!c[2]&&!c[3])return 0; int num=INF,t1=c[1],t2=c[2],t3=c[3]; // d[1]=c[1];d[2]=c[2];d[3]=c[3]; // memcpy(d,c,sizeof c); for(int i=1;i<=3;i++) { if(!c[i])continue; int t=c[i]; c[i]=0; num=min(num,dfs(c,l,t)); // c[i]=d[i]; c[1]=t1;c[2]=t2;c[3]=t3; } return f[now][c[1]][c[2]][c[3]]=num+1; } int main() { scanf("%d",&n); for(int i=1;i<=n;i++) { scanf(" %c",&ch); col[i]=num(ch); } printf("%d",dfs(tmp,1,10)); return 0; }