题目描述

有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. vue第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件)

    第六单元(vue的实例和组件-vue实例的相关属性和方法-解释vue的原理-创建vue的组件) #课程目标 掌握vue实例的相关属性和方法的含义和使用 了解vue的数据响应原理 熟悉创建组件,了解全局 ...

  2. mybatis-plus逻辑删除

    MP(mybatis plus)已经大大简化了我们好多的开发操作,基本的增删改查都有了,包括代码生成等等,今天想说的是它的逻辑删除功能.我们都在数据库设计时候经常会有is字段,表示是否删除,为了留下员 ...

  3. Codis集群相关

    在大数据高并发场景下,单个 Redis 实例往往会显得捉襟见肘.首先体现在内存上,单个 Redis 的内存不宜过大,内存太大会导致 rdb 文件过大,进一步导致主从同步时全量同步时间过长,在实例重启恢 ...

  4. js中点回车enter触发事件&layui弹窗按enter键不停弹窗问题的解决&js实现鼠标焦点自动落到文本框(layui)

     js中回车触发事件 一. document.onkeydown = function (e) { // 回车提交表单 // 兼容FF和IE和Opera var theEvent = window.e ...

  5. CyclicBarrier回环屏障深度解析

    1. 前沿 从上一节的CountDownLatch的学习,我们发现其只能使用一次,当state递减为0后,就没有用了,需要重新新建一个计数器.那么我们有没有可以复用的计数器呢?当然,JUC包给我们提供 ...

  6. sql中大于等于小于的写法

    由于在mybatis框架的xml中<= , >=解析会出现问题,编译报错,所以需要转译第一种写法: 原符号 < <= > >= & ' "替换符号 ...

  7. easyui中刷新列表

    <table class="crud-content-info" id="showProductDialogFormstandrad"> </ ...

  8. postgre sql递归查询

    WITH  RECURSIVE  r  AS (SELECT * FROM [表] WHERE id = xxxunion ALLSELECT [表].* FROM [表], r WHERE [表]. ...

  9. Echarts数据可视化,easyshu图表集成。

      介绍: ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE8/9/10/11,Chrome,Firefox,Sa ...

  10. 平滑算法:三次样条插值(Cubic Spline Interpolation)

    https://blog.csdn.net/left_la/article/details/6347373 感谢强大的google翻译. 我从中认识到了航位推算dead reckoning,立方体样条 ...