洛谷2530(codevs2098)化工厂装箱员

题目: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;
}
代码2

改了改上边之后的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;
}
代码3
原文地址:https://www.cnblogs.com/Narh/p/8671785.html