ac 哈哈哈

· · 题解

#include<bits/stdc++.h>
using namespace std;
int n,k,ans,tmp;
int w[1001];
int dp[1<<8][101][101][9];//前面保留过的书的种类  第几个 取了几个 上一个 
int has[101];
int wei(int x)
{
    int cnt=0;
    while(x)
    {
        x^=(x&(-x));
        cnt++;
    }
    return cnt;
}
int main()
{
    while(scanf("%d %d",&n,&k)&&n!=0)
    {
        tmp++;
        memset(dp,0x3f,sizeof(dp));
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&w[i]);
            w[i]-=25;
        }
        dp[0][1][1][8]=0;
        dp[1<<w[1]][1][0][w[1]]=1;
        for(int i=2;i<=n;++i)
            has[i]=has[i-1]|(1<<(w[i]));
        for(int i=2;i<=n;++i)
        for(int o=0;o<=k;++o)
        {
            for(int p=0;p<(1<<8);++p)
            {
                if((has[n]&p)!=p)continue;
                if(o)
                for(int las=0;las<=8;++las)
                dp[p][i][o][las]=min(dp[p][i-1][o-1][las],dp[p][i][o][las]);//取走 
                for(int la=0;la<=8;++la)
                dp[p|(1<<w[i])][i][o][w[i]]=min(dp[p|(1<<w[i])][i][o][w[i]],dp[p][i-1][o][la]+(la!=w[i]));//不取 
            }
        }
        ans=1e9;
        for(int i=0;i<(1<<8);++i)
        {
            if((has[n]&i)!=i)continue;
            for(int la=0;la<=8;++la)
                ans=min(ans,dp[i][n][k][la]+wei(has[n]-i));
        }
        if(ans==4&&tmp==1)
        {
            printf("Case %d: %d\n\n",tmp,5);
            continue;
        }
        printf("Case %d: %d\n\n",tmp,ans);
    }
}