zoukankan      html  css  js  c++  java
  • [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<bits/stdc++.h>
    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<<a[i];
        }
        f[0][0][8][0]=0;
        //f[i][j][k][mask],表示前i本书已经抽出了j本,
    	//前i本中没被抽出的书里最后一本书的高度是k,mask是一个0~2^8-1的二进制,
    	//表示前i本中没被抽出的书里高度的存在情况。
    	//整体表示前i本书中没被抽出的书组成的序列的最小混乱度。
        for(int i=0;i<n;i++) //前i本书 
            for(int j=0;j<=k;j++) //抽走了j本 
                for(int l=0;l<=8;l++) //没抽走了,最后一本的高度 
                    for(int s=0;s<1<<8;s++) //没抽走了,存在哪些高度 
                    {
    					//第i个没有被抽走 
                        f[i+1][j][a[i+1]][s|1<<a[i+1]]=min(f[i+1][j][a[i+1]][s|1<<a[i+1]],f[i][j][l][s]+(l!=a[i+1]));
                        if(j!=k) //如果还没有抽走K本,则第j本书是可以抽走的 
    					   f[i+1][j+1][l][s]=min(f[i+1][j+1][l][s],f[i][j][l][s]);
                    }
        int ans=1e9;
        for(int s=0;s<1<<8;s++) //枚举高度集合,没有抽走的 
        {
            int t=s^ss,cnt=0;
            //ss代表全集,t代表抽走的书的状态,如果本在没有抽走中的,为0,反之为1 
            for(int i=0;i<8;i++) //计算T集合的大小 
                cnt+=t>>i&1;
            for(int l=0;l<=8;l++)
                ans=min(f[n][k][l][s]+cnt,ans);
        }
        printf("%d
    ",ans);
        return 0;
    }
    

      

  • 相关阅读:
    PHP array_udiff_assoc() 函数
    PHP array_udiff() 函数
    app已损坏,打不开。你应该将它移到废纸篓
    [WC2013]糖果公园
    win10 uwp 绑定静态属性
    win10 uwp 修改Pivot Header 颜色
    win10 uwp 修改Pivot Header 颜色
    win10 uwp 修改Pivot Header 颜色
    win10 uwp 反射
    win10 uwp 反射
  • 原文地址:https://www.cnblogs.com/cutemush/p/13384427.html
Copyright © 2011-2022 走看看