最小最序列和以及最小正子序列

2024-05-04 23:48
文章标签 最小 序列 正子

本文主要是介绍最小最序列和以及最小正子序列,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.描述:最小子序列(序列之和最小)

  思路:用编程之美上的分治解法。子数组存在三种情况:

           (1)左边的字数组里面arr[1...n/2]

           (2)右边的子数组里面arr[n/2+1...n]

           (3)要么在中间 arr[start..n/2....end];

  代码:

#include<iostream>using namespace std;#define  max 100int findMinSubstr(int arr[],int start,int end)
{  if(start==end)return arr[start];  int left,right;  int result = max;int mid = start+((end-start)>>1);  left = findMinSubstr(arr,start,mid);  right = findMinSubstr(arr,mid+1,end);  int i = mid - 1;  int j = mid + 1;  int sum = arr[mid];  int minsum = max;  while(i>=start){  sum += arr[i];  if(sum<minsum)minsum = sum;  i--;  }  sum = minsum;  while(j<end){  sum += arr[j];  if(sum<minsum)minsum = sum;   j++;  }  if(minsum<left)return minsum<right?minsum:right;else return left<right?left:right;}  int main()
{int arr[]={-1,7,3,-3,6};cout<<findMinSubstr(arr,0,4)<<endl;system("pause");return 0;
}

2.描述:最小正子序列(序列之和最小,同时满足和值要最小)

   思路:

            (1)先求出数组的前缀数组之和,例如:2,-3,-3,7,5=>前缀数组和为2,-1,-4,3,8(它们的索引0 1 2 3 4)

            (2)对前缀数组进行排序得到:-4,-1,2,3,8(即是这样的:(-4,3)  (1,1)  (2,0)  (3,3,)  (8,4) )

            (3)则最小值一定是在:-4,1,2,3,8(结果一定在当前项减去前面一项,同时满足索引大于前一项的索引)

  代码:

#include<iostream>
#include<algorithm>using namespace std;#define max 100struct Item{int value;int rank;
};bool cmp(const Item&a,const Item& b)
{return a.value<b.value;
}int operator-(const Item&a,const Item& b)
{return a.value-b.value;
}bool operator>(const Item&a,const Item& b)
{return a.rank>b.rank;
}int findMaxPositiveSubstr(int arr[],int len)
{Item *tmp = new Item[len];int sum = 0;int i;  memset(tmp,0,sizeof(Item)*len);for(int i=0;i<len;i++){sum += arr[i];tmp[i].value = sum;}for(i=0;i<len;i++)tmp[i].rank = i;sort(tmp,tmp+len,cmp);int result = tmp[0].value>0?tmp[0].value:max;for(i=1;i<len;i++){if(tmp[i]>tmp[i-1]&&(tmp[i]-tmp[i-1])>0&&(tmp[i]-tmp[i-1])<result){result = tmp[i]-tmp[i-1];}}return result;
}int main()
{int arr[]={2,-3,-3,7,5};cout<<findMaxPositiveSubstr(arr,4)<<endl;system("pause");return 0;
}


 

3.描述:最大子序列乘积

  代码:

#include<iostream>  using namespace std;  #define  max 0;  
#define min -1;long int findMaxSubstr(int arr[],int start,int end)  
{    if(start==end)return arr[start];    long int left,right;    int mid = start+((end-start)>>1);    left = findMaxSubstr(arr,start,mid);    right = findMaxSubstr(arr,mid+1,end);    int i = mid - 1;    int j = mid + 1;    long int muilt = arr[mid]; long int minNegativeLeft = min;  long int minNegativeRight = min;long int maxPostiveLeft = max;long int maxPostiveRight = max;while(i>=start){    muilt *= arr[i];    if(muilt>0){if(muilt>maxPostiveLeft)maxPostiveLeft = muilt;}else{if(muilt<minNegativeLeft)minNegativeLeft = muilt;}  i--;    }    muilt = 1;while(j<end){    muilt *= arr[j];   if(muilt>0){if(muilt>maxPostiveRight)maxPostiveRight = muilt;}else{if(muilt<minNegativeRight)minNegativeRight = muilt;}    j++;    }    long int tmp = minNegativeLeft*minNegativeRight>maxPostiveLeft*maxPostiveRight?minNegativeLeft*minNegativeRight:maxPostiveLeft*minNegativeRight;if(tmp>left)return tmp>right?tmp:right;  else return left>right?left:right;  }    int main()  
{  int arr[]={-1,7,3,-3,-6};  cout<<findMaxSubstr(arr,0,5)<<endl;  system("pause");  return 0;  
}  


 

这篇关于最小最序列和以及最小正子序列的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/960364

相关文章

C++从序列容器中删除元素的四种方法

《C++从序列容器中删除元素的四种方法》删除元素的方法在序列容器和关联容器之间是非常不同的,在序列容器中,vector和string是最常用的,但这里也会介绍deque和list以供全面了解,尽管在一... 目录一、简介二、移除给定位置的元素三、移除与某个值相等的元素3.1、序列容器vector、deque

最长公共子序列问题的深度分析与Java实现方式

《最长公共子序列问题的深度分析与Java实现方式》本文详细介绍了最长公共子序列(LCS)问题,包括其概念、暴力解法、动态规划解法,并提供了Java代码实现,暴力解法虽然简单,但在大数据处理中效率较低,... 目录最长公共子序列问题概述问题理解与示例分析暴力解法思路与示例代码动态规划解法DP 表的构建与意义动

关于最长递增子序列问题概述

《关于最长递增子序列问题概述》本文详细介绍了最长递增子序列问题的定义及两种优化解法:贪心+二分查找和动态规划+状态压缩,贪心+二分查找时间复杂度为O(nlogn),通过维护一个有序的“尾巴”数组来高效... 一、最长递增子序列问题概述1. 问题定义给定一个整数序列,例如 nums = [10, 9, 2

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

poj 1734 (floyd求最小环并打印路径)

题意: 求图中的一个最小环,并打印路径。 解析: ans 保存最小环长度。 一直wa,最后终于找到原因,inf开太大爆掉了。。。 虽然0x3f3f3f3f用memset好用,但是还是有局限性。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#incl

hdu 1102 uva 10397(最小生成树prim)

hdu 1102: 题意: 给一个邻接矩阵,给一些村庄间已经修的路,问最小生成树。 解析: 把已经修的路的权值改为0,套个prim()。 注意prim 最外层循坏为n-1。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstri

uva 10131 最长子序列

题意: 给大象的体重和智商,求体重按从大到小,智商从高到低的最长子序列,并输出路径。 代码: #include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vect

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若