• 邦邦的大合唱站队


    洛咕

    题意:N个偶像排成一列,他们来自M个不同的乐队.每个团队至少有一个偶像.现在要求重新安排队列,使来自同一乐队的偶像连续的站在一起.重新安排的办法是,让若干偶像出列(剩下的偶像不动),然后让出列的偶像一个个归队到原来的空位,归队的位置任意.问最少让多少偶像出列?(n<=1e5,m<=20.)

    想了半个小时,没有思路,丢给了@(lyh),几分钟后,"我只想到了(70)分做法",又过了几分钟,"我会了(!!!)",再过几分钟,"我切了(!!!)".又是被包菜的一天.

    分析:分析一下样例,发现就是确定出一种排列,然后跟原先打乱的队列去一一比较,不同的就产生1的贡献.例如,

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

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

    不同的位置有7个,则这种方案的答案就是7.

    所以(70)分做法就是暴力枚举出所有的排列,然后一一比较取最小值.

    正解:(m<=20),状压(!!!).设(f[i])表示已经排好的乐队的集合状态为i时的最少出列数.

    (f[i]=min(f[i],f[i)^((1)<<((j-1))]+calc(j))),(calc(j))表示当前把编号为(j)的排进去产生的贡献,一一比较的话复杂度太高.

    可以预处理出(sum[i][j])表示前i个位置中编号为j的出现的次数.(pos[i])表示排好的乐队状态为(i)时排到了哪个位置.(pos[i]=sum_{j=1}^m sum[n][j],if(i)&((1)<<((j-1))==1))

    所以(calc(j)=sum[n][j]-(sum[pos[i]][j]-sum[pos[last]][j])),其中(last=i)^((1)<<((j-1)))

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=1e5+5;
    int a[N],sum[N][21],f[1050000],pos[1050000];
    int main(){
    	int n=read(),m=read();
    	for(int i=1;i<=n;++i)a[i]=read();
    	for(int i=1;i<=n;++i){
    		for(int j=1;j<=m;++j){
    			sum[i][j]=sum[i-1][j];
    			if(a[i]==j)++sum[i][j];
    		}
    	}
    	for(int i=1;i<(1<<m);++i)
    		for(int j=1;j<=m;++j)
    			if(i&(1<<(j-1)))pos[i]+=sum[n][j];
    	memset(f,0x3f,sizeof(f));f[0]=0;
    	for(int i=1;i<(1<<m);++i){
    		for(int j=1;j<=m;++j){
    			if(i&(1<<(j-1))){
    				int last=i^(1<<(j-1));
    				f[i]=min(f[i],f[last]+sum[n][j]-(sum[pos[i]][j]-sum[pos[last]][j]));
    			}
    		}
    	}
    	printf("%d
    ",f[(1<<m)-1]);
    	return 0;
    }
    
    
  • 相关阅读:
    akka并发编程练习
    使用selenium和chromedriver组合爬虫时,如果爬取的页面数量巨多,会出现占用内存逐渐增大知道程序崩溃的情况
    网易2017秋招编程题集合_以下代码全部来自牛客网
    牛客网_运行问题
    json和xml之间转换的好文
    Eclipse 启动时闪退问题解决方案
    关于opencv的文件配置详细内容
    第一个opencv声称图片_以及遇到的问题集锦
    好文收藏_关于find_first_not_of函数
    好文收藏readtxt_cpp
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11733199.html
Copyright © 2020-2023  润新知