题目描述

有N个人,来自K个家族.他们排成一行准备照相,但是由于天生的排外性,每个人都希望和本家族的人站在一起,中间不要加入别的家族的人.问最少从队列中去掉多少个就可以达到这个目的.

输入格式

第一行给出N,K。N在[1,100],K在[1,5]

第二行给出N个数,每个数为1到K中的某个数。

输出格式

最少从队列中去掉多少个就可以达到这个目的


显然对于当前第i个点我们可以做两个操作:留下或者删去。

如果留下,就会有两种情况:第i个人和上一个留下的人属于同一个家族。第二种情况是不属于同一个家族,那么我们的状态需要从当前有人留下的家族转移过来。

如果删去则不需要考虑任何东西。

综合上面的分析,可以知道我们需要的信息有:当前是第几个人,当前选了那些家族,处理完当前人之后最后一个留下的人的家族。

那么可以设计出这样的状态:dp(i,j,k),表示当前为第i个人,当前选的家族情况的二进制表示为j,最后一个留下的人的家族为k。设第i个人的家族为col,那么可以得出状态转移方程:

\[dp[i][j][col]=Max_{1≤k≤K}{\{}dp[i-1][j{\wedge}R(1<<col)][k]+1{\}}
\]

初始化都为0,答案为n-Max{dp(n,i,j)}

时间复杂度为O(NK * 2^K)。

#include<iostream>
#include<cstring>
#include<cstdio>
#define maxn 101
#define maxm 6
using namespace std; int dp[maxn][1<<maxm][maxm];
int n,m,ans;
inline int read(){
register int x(0),f(1); register char c(getchar());
while(c<'0'||'9'<c){ if(x=='-') f=-1; c=getchar(); }
while('0'<=c&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
} int main(){
//freopen("photo.in","r",stdin);
//freopen("photo.out","w",stdout);
n=read(),m=read(); for(register int i=1;i<=n;i++){
int col=read()-1;
memcpy(dp[i],dp[i-1],sizeof dp[i-1]);
for(register int j=0;j<1<<m;j++) if(j&(1<<col)){
dp[i][j][col]=max(dp[i][j][col],dp[i-1][j][col]+1);
for(register int k=0;k<m;k++){
dp[i][j][col]=max(dp[i][j][col],dp[i-1][j^(1<<col)][k]+1);
}
}
}
for(register int i=0;i<1<<m;i++){
for(register int j=0;j<m;j++){
ans=max(ans,dp[n][i][j]);
}
}
printf("%d\n",n-ans);
return 0;
}

入门OJ:photo的更多相关文章

  1. 【入门OJ】2003: [Noip模拟题]寻找羔羊

    这里可以复制样例: 样例输入: agnusbgnus 样例输出: 6 这里是链接:[入门OJ]2003: [Noip模拟题]寻找羔羊 这里是题解: 题目是求子串个数,且要求简单去重. 对于一个例子(a ...

  2. 【大视野入门OJ】1099:歌德巴赫猜想

    Description 歌德巴赫猜想大家都很熟悉吧?给一个数,能够分解成两个素数的和.现在要给你一个n,6 <= n < 1000000,让你求他会分解成哪两个素数?如果存在多组解,则要求 ...

  3. 【大视野入门OJ】1083:数组的二分查找

    Description 在1500个整数中查整数x的位置,这些数已经从小到大排序了.若存在则输出其位置,若不存在则输出-1. Input 第一行,一个整数x 后面1500行,每行一个整数 Output ...

  4. 入门oj 6492: 小B的询问

    Description 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数字i在[L ...

  5. 入门oj 5499: 讲话模式

    Description 每个人说话都有口头禅,现给出一个字符串,请求出其中出现次数最多的单词(不区分大小写). Input 输入一行,长度小于等于1048576的字符串输入至少包含一个字母或数字 Ou ...

  6. 入门oj 6451: The XOR Largest Pair之二

    Description 今天小W用了1s不到的时候完成了这样一个题:在给定的N个整数 A_1,A_2,-,A_N中选出两个进行异或运算,得到的结果最大是多少?正当他志得意满时,L老师亮出了另一个题:给 ...

  7. 入门OJ:简单的网络游戏

    题目描述 在某款极具技术含量的网络游戏中,佳佳靠着他的聪明智慧垄断了游戏中的油田系统.油田里有许多油井,这些油井排成一个M*N的矩形.每个油井都有一个固定的采油量.每两个相邻的油井之间有一条公路,这些 ...

  8. 入门OJ:Coin

    题目描述 你有n个硬币,第i硬币面值为ai,现在总队长想知道如果丢掉了某个硬币,剩下的硬币能组成多少种价值?(0价值不算) 输入格式 第一行一个整数n 第二行n个整数.,a1,a2-an. 1< ...

  9. 入门OJ:最短路径树入门

    题目描述 n个城市用m条双向公路连接,使得任意两个城市都能直接或间接地连通.其中城市编号为1..n,公路编号为1..m.任意个两个城市间的货物运输会选择最短路径,把这n*(n-1)条最短路径的和记为S ...

随机推荐

  1. 面试 16-01.MVVM

    16-01.MVVM #前言 MVVM的常见问题: 如何理解MVVM 如何实现MVVM 是否解读过Vue的源码 题目: 说一下使用 jQuery 和使用框架的区别 说一下对 MVVM 的理解 vue ...

  2. Spark性能调优九之常用算子调优

    1.使用mapPartitions算子提高性能 mapPartition的优点:使用普通的map操作,假设一个partition中有1万条数据,那么function就要被执行1万次,但是使用mapPa ...

  3. 图解HTTP权威指南 | HTTP报文

                                                                                    一.问题 1.报文流是如何流动的 2.H ...

  4. C#未能找到类型或命名空间名称xxxxxx的可能原因

    常见原因 原因:使用的.NET版本不一样 今天又被这问题撞上了,结果神奇般的解决了 谷歌了很久都没有找到真正有用的解决方案,所以在这儿写下,让更多的人看到 最根本的原因其实就是引用的问题,引用错了,然 ...

  5. 老吕教程--02后端KOA2框架自动重启编译服务(nodemon)

    上一篇讲完搭建Typescritp版的Koa框架后,F5运行服务端,页面进行正常显示服务. 今天要分享的是,如果要修改服务端代码,如果让编译服务自动重启,免去手动结束服务再重启的过程. 自动重启服务需 ...

  6. 简单了解一下 Nginx

    一.Nginx 基本认识 1.Nginx 是什么? Nginx 是一款开源的.轻量级的.高性能的 HTTP 服务器 以及 反向代理服务器. 特点是 占有内存少.并发能力强. 2.Nginx 用来干什么 ...

  7. CSS系列 (03):CSS三大特性

    层叠性 层叠性指的是样式的优先级,当产生冲突时以优先级高的为准,优先级相同时取后面定义的属性样式. 继承性 继承性指的是子孙元素可以继承父元素的属性. 记录一下开发中常用的继承属性: 字体系列 fon ...

  8. Vitis AI--个人调试篇

    一.下载VITIS-AI的仓库 单独git clone很慢,因此先将其导入到gitee平台,再执行clone 1. Import VITIS-AI github repo into gitee rep ...

  9. [leetcode]297. Serialize and Deserialize Binary Tree一般二叉树的编解码

    由于一般的前序遍历不能唯一的还原出原本你的二叉树,所以要改变一下: 记录二叉树的结构信息,也就是空节点用符号表示 一般的前序遍历只是记录了节点的前后顺序,通过记录空节点,每一层的结构就可以记录下来 解 ...

  10. String类型 堆/字符串池的理解

    1 package test; 2 3 public class StringTest { 4 5 public static void main(String[] args) { 6 7 /** 8 ...