1 条题解

  • 0
    @ 2025-9-9 23:54:49

    C++ :

    #include<cstdio>
    #include<cstring>
    using namespace std;
    #define min(a,b) ((a)<(b)?(a):(b))
    #define inf ((1<<30)-1)
    int dp[2][105][1<<8][10];
    int tall[105],num[1<<8];
    int main()
    {
        int n,m,begin;
        //预处理
        memset(num,0,sizeof(num));
        for(int i=0; i<(1<<8); ++i)
            for(int j=0; j<8; ++j)
                if(i&(1<<j)) num[i]++;
        for(int cas=1;~scanf("%d%d",&n,&m);++cas)
        {
            if(n+m==0) break;
            begin=0;//初始高度状态
            for(int i=1; i<=n; ++i)
            {
                scanf("%d",&tall[i]);
                tall[i]-=25;
                begin=begin|(1<<tall[i]);
            }
            for(int i=0; i<=m; ++i)//取走的次数
                for(int j=0; j<(1<<8); ++j)//高度状态
                    for(int k=0; k<=8; ++k)//最后的书的高度
                        dp[0][i][j][k]=inf;
            dp[0][0][0][8]=0;//起始点
            for(int i=1; i<=n; ++i)
            {
                for(int j=0; j<=m; ++j)
                    for(int k=0; k<(1<<8); ++k)
                        for(int s=0; s<=8; ++s)
                            dp[i&1][j][k][s]=inf;
                for(int j=0; j<i&&j<=m; ++j)
                    for(int k=0; k<(1<<8); ++k)
                        for(int s=0; s<=8; ++s)
                            if(dp[(i-1)&1][j][k][s]!=inf)
                            {
                                //取走第i位
                                if(j<m)        dp[i&1][j+1][k][s]=min(dp[i&1][j+1][k][s],dp[(i-1)&1][j][k][s]);
                                //不取走第i位且高度与前一个相同
                                if(s==tall[i]) dp[i&1][j][k][s]=min(dp[i&1][j][k][s],dp[(i-1)&1][j][k][s]);
                                //不取走第i位且高度与前一个不同
                                else           dp[i&1][j][k|(1<<tall[i])][tall[i]]=min(dp[i&1][j][k|(1<<tall[i])][tall[i]],dp[(i-1)&1][j][k][s]+1);
                            }
            }
            int ans=inf;
            for(int i=0; i<=m; ++i)
                for(int j=0; j<(1<<8); ++j)
                    for(int k=0; k<8; ++k)
                        if(dp[n&1][i][j][k]!=inf)
                        {
                            int temp=j^begin;//不在此状态且拿出的书的高度
                            if(ans>dp[n&1][i][j][k]+num[temp])
                                ans=dp[n&1][i][j][k]+num[temp];
                        }
            printf("Case %d: %d\n\n",cas,ans);
        }
        return 0;
    }
    
    
    • 1

    信息

    ID
    1830
    时间
    2000ms
    内存
    128MiB
    难度
    (无)
    标签
    递交数
    0
    已通过
    0
    上传者