Chinaunix首页 | 论坛 | 博客
  • 博客访问: 986553
  • 博文数量: 150
  • 博客积分: 3017
  • 博客等级: 少校
  • 技术积分: 3829
  • 用 户 组: 普通用户
  • 注册时间: 2011-11-19 14:40
个人简介

Now in Baidu WISE team

文章分类

全部博文(150)

文章存档

2014年(8)

2013年(31)

2012年(111)

分类: C/C++

2012-10-20 18:14:09

一串首尾相连的珠子(m个),有N种颜色(N《=10),设计一个算法,取出其中一段,要求包含所有N中颜色,并使长度最短。并分析时间复杂度与空间复杂度。

真是不好做唉。。和一般的DP不是很一样。做了很久了。一直不是十分能想通,最后的代码写的也很繁复,不简练。

点击(此处)折叠或打开

  1. /*
  2.  * =====================================================================================
  3.  *
  4.  * Filename: bead.c
  5.  *
  6.  * Description:
  7.  *
  8.  * Version: 1.0
  9.  * Created: 10/20/2012 11:46:48 AM
  10.  * Revision: none
  11.  * Compiler: gcc
  12.  *
  13.  * Author: royn.wang.renyuan@gmail.com (),
  14.  * Organization:
  15.  *
  16.  * =====================================================================================
  17.  */
  18. #include <stdlib.h>
  19. #include <stdio.h>

  20. #define MAXK 10
  21. #define    MAXM 100            /* */
  22. int getfirstvalue(int *input,int n){
  23.     int match = (1<<n)-1;
  24.     int end = -1;
  25.     int v = 0;
  26.     do{
  27.         end++;
  28.         v |= 1<<input[end];
  29.     }while(v!=match);
  30.     return end;
  31. }
  32. int getnextoccur(int tarindex, int *input, int size){
  33.     int i;
  34.     for(i = tarindex+1;i<size*2;i++){
  35.         if( input[i%size] == input[tarindex])
  36.             return i%size;
  37.     }
  38.     return -1;
  39. }

  40. /*
  41.  * === FUNCTION ======================================================================
  42.  * Name: main
  43.  * Description:
  44.  * =====================================================================================
  45.  */
  46.     int
  47. main ( int argc, char *argv[] )
  48. {
  49.     int input[] = {0,1,2,3,4,4,5,4,2,3,1,0,2,3};
  50.     int n = 6;
  51.     int size = sizeof(input)/sizeof(int);
  52.     int next[size];
  53.     int end[size];
  54.     int i = 0;
  55.     end[0] = getfirstvalue(input,n);
  56.     int minlen = end[0];
  57.     for(;i<size;i++){
  58.         next[i] = getnextoccur(i,input,size);
  59.     }
  60.     for(i = 1; i<size;i++){
  61.         end[i] = end[i-1] ;
  62.         if( (end[i]>i && (next[i-1] < i || next[i-1]>end[i]))
  63.             ||
  64.             (end[i]<i && next[i-1] > end[i] && next[i-1]<i)
  65.             ){
  66.             end[i] = next[i-1];
  67.         }
  68.         printf ( "start = %d end = %d\n", i,end[i] );
  69.         int tmp = end[i]>i?end[i]-i+1 : size-i+end[i];
  70.         minlen = tmp>minlen?minlen:tmp;
  71.     }
  72.     printf ( "min length = %d\n", minlen );
  73.     return EXIT_SUCCESS;
  74. }                /* ---------- end of function main ---------- */

阅读(2350) | 评论(2) | 转发(1) |
给主人留下些什么吧!~~

runningdark2012-10-25 19:49:17

momser: 学习了
我在gcc上跑了一下,应该有14种取法吧,每个珠子开头都可以算出一个最小值
我跑出来是从1-13只有13个,哪里出了点小问题呢?.....
这题当时做的不顺, 一直也没想出特好的算法,所以才没写解释。
end[0] = getfirstvalue(input,n);
这句算出了第一个珠子起头的最小值,没有输出。动态规划总是要有第一个初始值,才能继续后续递推,所以这个并不在循环内。循环是从i=1开始的。
我自己总觉得end[0]这步很多余但是也想不到其他办法。囧。另外你提醒我了确实有一步错误minlen的初始值不对。现在我更新下。

momser2012-10-23 19:49:26

学习了
我在gcc上跑了一下,应该有14种取法吧,每个珠子开头都可以算出一个最小值
我跑出来是从1-13只有13个,哪里出了点小问题呢?