Chinaunix首页 | 论坛 | 博客
  • 博客访问: 65022
  • 博文数量: 115
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 10
  • 用 户 组: 普通用户
  • 注册时间: 2014-03-08 19:09
文章分类
文章存档

2015年(115)

我的朋友

分类: C/C++

2015-08-06 16:46:03

1.多人排成一个队列,我们认为从低到高是正确的序列,但是总有部分人不遵守秩序。如果说,前面的人比后面的人高(两人身高一样认为是合适的), 那么我们就认为这两个人是一对“捣乱分子”,比如说,现在存在一个序列:
176, 178, 180, 170, 171
这些捣乱分子对为
<176, 170>, <176, 171>, <178, 170>, <178, 171>, <180, 170>, <180, 171>,
那么,现在给出一个整型序列,请找出这些捣乱分子对的个数(仅给出捣乱分子对的数目即可,不用具体的对)
要求:
输入:
为一个文件(in),文件的每一行为一个序列。序列全为数字,数字间用”,”分隔。
输出:
为一个文件(out),每行为一个数字,表示捣乱分子的对数。
详细说明自己的解题思路,说明自己实现的一些关键点。
并给出实现的代码,并分析时间复杂度。
限制:
输入每行的最大数字个数为100000 个,数字最长为6 位。程序无内存使用限制。
 
该题一看明显ACM搬过来的。直观感受DP,但是还想了挺久。给出的DP算法是核心算法,存储结构如果用线段树来处理数据结构可以优化不少。但是就题干给出的数据,直接使用二维数组就足够而且简单了。
 
设f(i,v)为从下标为i的元素开始,其后面值不小于input[i]的值的个数,即从i开始向后,非捣乱分子的个数。
那么有,
           f(i-1,v) = f(i,v) + 1(input[i]<=v)
                      f(i,v)    (input[i]>v)
捣乱分子个数g(i,v) = size - i -f(i-1,v)
求和即可。
 
该算法复杂度为O(n*m),m为输入数据的最小值与最大值的差值。
 
该算法空间复杂度较高(DP的空间换时间特性),而且时间复杂度和输入数据的分布有关。如果说所有数据都不相等,且差值较大,该算法就会严重退化。(此处如果使用线段树存储数据,可以大大减少空间时间复杂度,不过数据结构的处理就会变得挺麻烦了)。
如果如题目中给出的类似于身高的数据范围很小,给出的算法就非常合适了。
网络上给出的多为类于归并排序的算法,不赘述。
 
 
 

点击(此处)折叠或打开

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #define MAX 1000
  4. int result[MAX][MAX] = {{0}};
  5. void fillResult(int * input, int size, int min, int max){
  6.     int i = size -1;
  7.     for(;i>= 0 ; i--){
  8.         int v = min;
  9.         for(;v<=max;v++){
  10.             result[v][i] = v<=input[i]?(result[v][i+1] + 1) : result[v][i+1];
  11.             printf("%d, %d = %d \n", v,i,result[v][i]);
  12.         }
  13.     }
  14. }
  15. int mygetCount(int * input, int size){
  16.     int count = 0;
  17.     int i = 0;
  18.     for(;i<size;i++){
  19.         count += (size-i- result[input[i]][i]);
  20.         printf("count = %d \n", count);
  21.     }
  22.         return count;
  23. }

  24. int main(){
  25.     int input[] = {1,3,2,5,4};
  26.     fillResult(input, sizeof(input)/sizeof(int), 1, 5);
  27.     printf("%d \n", mygetCount(input, sizeof(input)/sizeof(int)));
  28. }

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