[Noip模拟题]帮助Bsny

Bsny的书架乱成一团了,帮他一下吧!他的书架上一共有n本书,我们定义混乱值是连续相同高度书本的段数。例
如,如果书的高度是30,30,31,31,32,那么混乱值为3;30,32,32,31的混乱值也为3。但是31,32,31,32
,31的混乱值为5,这实在是太乱了。Bsny想尽可能减少混乱值,但他有点累了,所以他决定最多取出k本书,再随
意将它们放回到书架上。你能帮助他吗?
Input
第一行两个整数n,k,分别表示书的数目和可以取出的书本数目。
接下来一行n个整数表示每本书的高度。
1≤k≤n≤100,注意所有书本高度在[25,32]
Output
仅一行一个整数,表示能够得到的最小混乱值。

Sample Input
5 1
25 26 25 26 25
Sample Output
3

Sol

N高度差很小,可以对这个宽度只有8的高度差状态压缩进行DP。每本书抽出来后,要么放在和它等高的书旁边,要不放在一边作为一个新的高度。
状态为:f[i][j][k][mask],表示前i本书已经抽出了j本,前i本中没被抽出的书里最后一本书的高度是k,mask是一个0~2^8-1的二进制,表示前i本中没被抽出的书里高度的存在情况。整体表示前i本书中没被抽出的书组成的序列的最小混乱度。
然后枚举第i本书是否被抽出。

#include
using namespace std;
int a[110],f[101][101][9][1<<8];
int main()
{
//  freopen("help.in","r",stdin);
//  freopen("help.out","w",stdout);
    memset(f,0x3f,sizeof(f));
    int n,k,ss=0;
    scanf("%d%d",&n,&k);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",a+i);
        a[i]-=25;
        ss|=1<>i&1;
        for(int l=0;l<=8;l++)
            ans=min(f[n][k][l][s]+cnt,ans);
    }
    printf("%d\n",ans);
    return 0;
}

  

你可能感兴趣的:([Noip模拟题]帮助Bsny)