我们的男主现在手中有n*c张牌,其中有c(<=4)种颜色,每种颜色有n(<=100)张,现在他要排序,首先把相同的颜色的牌放在一起,颜色相同的按照序号从小到大排序。现在他想要让牌的移动次数最小,问移动的最小次数是多少。

【LIS】因为颜色种类相当少,可以枚举排序后颜色的次序。相同颜色的纸牌从小到大排序,所以所有纸牌的最终顺序也就确定了。

然后就是怎么样移动纸牌能够使纸牌成为最终的顺序。

因为从给定序到有序的移动次数等于从有序到给定序,所以我们反着想,对于有序的序列,移动一张纸牌,那么它的最长不降序列就减少1。如果移动多个呢,只要求出其中没有改变的最大长度即可,这个长度就是原序列的最长不降序列。

一般的,如果给定序的最长不降序列是x,那么到有序状态的移动次数一定是n*c-x

  1. #include<bits/stdc++.h>
  2. #define eps 1e-9
  3. #define FOR(i,j,k) for(int i=j;i<=k;i++)
  4. #define MAXN 1005
  5. #define MAXM 40005
  6. #define INF 0x3fffffff
  7. using namespace std;
  8. typedef long long LL;
  9. struct node
  10. {
  11. int c,w,hash;
  12. }p[];
  13.  
  14. int i,j,k,n,m,x,y,T,ans,big,cas,num,len;
  15. bool flag;
  16. int ord[],c;
  17. bool vis[];
  18.  
  19. bool cmp(node a,node b)
  20. {
  21. return a.hash<b.hash;
  22. }
  23.  
  24. void work()
  25. {
  26. for (int i=;i<=n*c;i++)
  27. {
  28. p[i].hash=ord[p[i].c]*+p[i].w;//给每个元素一个唯一标识,按照这个标识来求最长不下降子序列
  29. }
  30.  
  31. int dp[],num;
  32. dp[]=;
  33. num=;
  34. for (int i=;i<=n*c;i++)
  35. {
  36. if (p[i].hash>=dp[num])
  37. {
  38. dp[++num]=p[i].hash;
  39.  
  40. }else
  41. {
  42. k=upper_bound(dp+,dp++num,p[i].hash)-dp;
  43. dp[k]=p[i].hash;
  44. }
  45. }
  46.  
  47. ans=min(ans,n*c-num);
  48. }
  49.  
  50. void dfs(int f)
  51. {
  52. for (int i=;i<=c;i++)
  53. {
  54. if (!vis[i])
  55. {
  56. vis[i]=;
  57. ord[f]=i;
  58. if (f==c) work();else dfs(f+);//枚举完毕后进入work()计算最长不下降子序列
  59. vis[i]=;
  60. }
  61. }
  62. }
  63.  
  64. int main()
  65. {
  66. scanf("%d%d",&c,&n);
  67. ans=INF;
  68. for (i=;i<=c*n;i++)
  69. {
  70. scanf("%d%d",&p[i].c,&p[i].w);
  71. }
  72. memset(vis,,sizeof(vis));
  73. dfs();//DFS枚举颜色次序
  74. printf("%d\n",ans);
  75. return ;
  76. }

SPOJ 4053 - Card Sorting 最长不下降子序列的更多相关文章

  1. SPOJ 3943 - Nested Dolls 最长不下降子序列LIS(二分写法)

    现在n(<=20000)个俄罗斯套娃,每个都有宽度wi和高度hi(均小于10000),要求w1<w2并且h1<h2的时候才可以合并,问最少能剩几个. [LIS]乍一看跟[这题]类似, ...

  2. 最长不下降子序列(LIS)

    最长上升子序列.最长不下降子序列,解法差不多,就一点等于不等于的差别,我这里说最长不下降子序列的. 有两种解法. 一种是DP,很容易想到,就这样: REP(i,n) { f[i]=; FOR(j,,i ...

  3. 最长不下降子序列 O(nlogn) || 记忆化搜索

    #include<stdio.h> ] , temp[] ; int n , top ; int binary_search (int x) { ; int last = top ; in ...

  4. tyvj 1049 最长不下降子序列 n^2/nlogn

    P1049 最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 ...

  5. 最长不下降子序列的O(n^2)算法和O(nlogn)算法

    一.简单的O(n^2)的算法 很容易想到用动态规划做.设lis[]用于保存第1~i元素元素中最长不下降序列的长度,则lis[i]=max(lis[j])+1,且num[i]>num[j],i&g ...

  6. 最长不下降子序列//序列dp

    最长不下降子序列 时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数第二行n个数 输出格式 最长不下降 ...

  7. 【tyvj】P1049 最长不下降子序列

    时间: 1000ms / 空间: 131072KiB / Java类名: Main 描述 求最长不下降子序列的长度 输入格式 第一行为n,表示n个数 第二行n个数 输出格式 最长不下降子序列的长度 测 ...

  8. hdu 4604 Deque(最长不下降子序列)

    从后向前对已搜点做两遍LIS(最长不下降子序列),分别求出已搜点的最长递增.递减子序列长度.这样一直搜到第一个点,就得到了整个序列的最长递增.递减子序列的长度,即最长递减子序列在前,最长递增子序列在后 ...

  9. 最长不下降子序列nlogn算法详解

    今天花了很长时间终于弄懂了这个算法……毕竟找一个好的讲解真的太难了,所以励志我要自己写一个好的讲解QAQ 这篇文章是在懂了这个问题n^2解决方案的基础上学习. 解决的问题:给定一个序列,求最长不下降子 ...

随机推荐

  1. display:inline 跟 display:block 跟 display:inline-block区别

    我来说句人话吧.display:inline; 内联元素,简单来说就是在同一行显示.display:block; 块级元素,简单来说就是就是有换行,会换到第二行.display:inline-bloc ...

  2. Python 环境

    文章出处:http://www.cnblogs.com/winstic/,请保留此连接 总结一下自己使用python过程中安装三方包的方法 Python 安装 Python的安装非常简单,本人使用的w ...

  3. 获取工程的exe文件的所在目录

    Assembly.GetExecutingAssembly().ManifestModule.FullyQualifiedName; 例如结果为:           C:\Documents and ...

  4. 【Java】Hibernate4实战 之 第一部分Hibernate入门

    Hibernate是什么:ORMapping的原理 Hibernate是轻量级的ORMapping框架. ORMapping基本规则: 类和表映射. 实例和数据库表中的一条数据映射. 实例的属性和数据 ...

  5. AV 地址错误 map 文件 根据地址报错,查 Delphi 代码

    1. 首先需要设置程序生成 map 文件.Project -> Options -> Linker -> Map file , Detailed 2. 计算公式Edit2.Text ...

  6. ASP.NET页面不被缓存

    设置ASP.NET页面不被缓存分类:ASP.NET (3531) (1) /// <summary>         /// 设置页面不被缓存         /// </summa ...

  7. Eqs (哈希)

    Time Limit: 5000MS   Memory Limit: 65536K Total Submissions: 10695   Accepted: 5185 Description Cons ...

  8. UVA-11983-Weird Advertisement(线段树+扫描线)[求矩形覆盖K次以上的面积]

    题意: 求矩形覆盖K次以上的面积 分析: k很小,可以开K颗线段树,用sum[rt][i]来保存覆盖i次的区间和,K次以上全算K次 // File Name: 11983.cpp // Author: ...

  9. datetime和timer的使用(小小幻灯片)

    一:展示图片 每秒换一次图片,一共六十张图片,00-59 二:代码 a,设计代码 namespace timePicture { partial class Form1 { /// <summa ...

  10. 暴力求解——POJ 3134Power Calculus

    Description Starting with x and repeatedly multiplying by x, we can compute x31 with thirty multipli ...