• P3694 邦邦的大合唱站队


    题目背景

    BanG Dream!里的所有偶像乐队要一起大合唱,不过在排队上出了一些问题。

    题目描述

    N个偶像排成一列,他们来自M个不同的乐队。每个团队至少有一个偶像。

    现在要求重新安排队列,使来自同一乐队的偶像连续的站在一起。重新安排的办法是,让若干偶像出列(剩下的偶像不动),然后让出列的偶像一个个归队到原来的空位,归队的位置任意。

    请问最少让多少偶像出列?

    输入输出格式

    输入格式:

    第一行2个整数N,M。

    接下来N个行,每行一个整数(a_i(1le a_i le M)),表示队列中第i个偶像的团队编号。

    输出格式:

    一个整数,表示答案

    输入输出样例

    输入样例#1: 复制

    12 4
    1
    3
    2
    4
    2
    1
    2
    3
    1
    1
    3
    4

    输出样例#1: 复制

    7

    说明

    【样例解释】

    1  3   √
    3  3
    2  3   √
    4  4
    2  4   √
    1  2   √
    2  2
    3  2   √
    1  1
    1  1
    3  1   √
    4  1   √
    

    【数据规模】

    对于全部数据,(1le Nle 10^5, Mle 20)


    (Mle 20)瞩目
    容易联想到状压
    然后这道题就做完了

    #include<iostream>
    #include<cstdio>
    
    using namespace std;
    
    int i,m,n,j,k,a[100001],f[1100001],s[100001][21],e[1100001],d[1100001];
    
    int main()
    {
        for(i=0;i<=20;i++) e[1<<i]=i+1; 
        scanf("%d%d",&n,&m);
        for(i=1;i<=n;i++) 
        {
            scanf("%d",&a[i]);
            for(j=1;j<=m;j++) s[i][j]=s[i-1][j];
            s[i][a[i]]=s[i-1][a[i]]+1;
        }
        for(i=1;i<=(1<<m)-1;i++)
        {
            k=i;
            while(k)
            {
                int x=k & -k;
                if(!d[i]) d[i]=d[i-x]+s[n][e[x]];
                f[i]=max(f[i],f[i-x]+s[d[i]][e[x]]-s[d[i-x]][e[x]]);
                k-=x;
            }
        }
        printf("%d",n-f[(1<<m)-1]);
    }
    
  • 相关阅读:
    vs entityframwork Validation failed for one or more entities
    samba配置
    Python中list的拷贝问题
    Android文件存储
    Java接口回调模拟按钮监听
    Android更新UI的五种方式
    Android handler学习笔记
    FBReaderJ学习笔记(四):SelectionPopup样式更改
    FBReaderJ学习笔记(三):Footer底部状态栏更改
    FBReaderJ学习笔记(五):附录
  • 原文地址:https://www.cnblogs.com/ZUTTER/p/9885236.html
Copyright © 2020-2023  润新知