问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

c语言(高分)

发布网友 发布时间:2022-04-12 14:28

我来回答

12个回答

懂视网 时间:2022-04-12 18:50

最长上升子序列 概念 维基百科-Longest Increasing Subsequence 算法一:动态规划 数据定义: a[] : 输入序列 d[] : 保存最长升序子序列的子问题。 d[i] 表示以a[i]结尾的最长子序列的长度。 d[]初始化为1。因为子序列最短也是1。 n : a 和 d的长度 状态转移

最长上升子序列

概念 维基百科->Longest Increasing Subsequence


算法一:动态规划

数据定义:

a[] : 输入序列

d[] : 保存最长升序子序列的子问题。

d[i] 表示以a[i]结尾的最长子序列的长度。

d[]初始化为1。因为子序列最短也是1。

n : a 和 d的长度

状态转移方程:

d[0] = 1 当i = 0

d[i] = 1 + max{d[j], a[i] > a[j] && 0 <= j < i) 当0

注解:在序列a[0],a[1],a[2],...,a[i-1]中找到最长的一个上升子序列,并且a[i]可以添加在它的末尾,使成为一个更长的上升子序列

时间复杂度分析:

求解一个d[i]需要一个循环取最大值,时间复杂度为O(n),所以总的时间复杂度是 O(n^2)。

程序使用双重循环构造d数组,最后遍历d数值去最大值。


-------------------------------------华丽的分割线------------------------------------------


算法二:贪心 + 二分搜索

数据定义补充:

开一个栈,将a[0]入栈,每次取栈顶元素top和读到的元素a[i](0 top 则将a[i]入栈;如果a[i]<= top则二分查找栈中的比a[i]大的第1个数,并用a[i]替换它。 最长序列长度即为栈的大小top。

这是很好理解的,对于x和y,如果x < y且stack[y] < stack[x],用stack[x]替换stack[y],此时的最长序列长度没有改变,但序列继续变长的'潜力'增大了。

举例:原序列为1,5,8,3,6,7

开始1,5,8相继入栈,此时读到3,用3替换5,得到1,3,8;

再读6,用6替换8,得到1,3,6;

再读7,得到最终栈为1,3,6,7。最长递增子序列为长度4。


伪代码描述:

初始化栈s

top = 0;

s[top] = a[i];

for (i = 1; i < n; i++)

if a[i] > s[top] // 将a[i]接在s[top]所代表的子串之后得到一个更长的子序列

top = top + 1

b[top] = a[i]

else

使用二分查找到这样一个j,使得s[j] < a[i] && a[i] <= s[j + 1]

s[j + 1] = a[i]

return : top + 1

算法分析:

内层循环由于b序列的严格递增性,可以使用二分查找,时间复杂度为O(log n),乘以外层循环,最终时间复杂度为O(n log n)。


注意:当出现1,5,8,2这种情况时,栈内最后的数是1,2,8不是正确的序列,难道错了?

分析一下,我们可以看出,虽然有些时候这样得不到正确的序列,但最后算出来的个数是没错的,为什么呢?

想想,当a[i]>top时,总个数直接加1,这肯定没错;但当a[i]

这两种情况的分析可以看出,如果只求个数的话,这个算法比较高效;但如果要求打印出序列时,就只能用动态规划了。


附上C++代码:

#include 
#include 
using namespace std;
//dp[i] 表示以A[0~i]的最长上升子序列的长度
//dp[0] = 1 当i=0
//dp[i] = 1 + max{dp[j], 0= 0) {
		s.push(seq[k]);
		k = pre[k];
	}
	while (!s.empty()) {
		cout << s.top() << "|";
		s.pop();
	}
	cout << endl;
	delete[] dp;
	delete[] pre;
	return max;
}

//找到一个j满足 array[j] < key <= array[j+1] 区间二分搜索
//返回j+1
int binary_search(int array[], int key, int low, int high) {
	while (low <= high) {
		int mid = (low + high) / 2;
		if (array[mid] < key && key <= array[mid+1]) { 
			//由于array严格单调递增,又key >= array[high]
			//mid+1不会溢出,想想为什么
			return mid + 1;
		}
		if (array[mid] < key) {
			low = mid + 1;
		} else {
			high = mid - 1;
		}
	}
}

int lis_greedy(int seq[], int n) {
	int top = 0;
	int* stack = new int[n];
	for (int i = 0; i < n; ++i) {
		stack[i] = 0;
	}
	stack[top] = seq[0];
	for (int i = 0; i < n; ++i) {
		if (seq[i] > stack[top]) {
			//如果seq[i]大于栈顶元素,则入栈
			stack[++top] = seq[i];
		} else {
			//从栈底开始,找到第一个>=seq[i]的元素所在位置
			int replace = binary_search(stack, seq[i], 0, top);
			stack[replace] = seq[i];
		}
	}
	for (int i = 0; i <= top; i++) {
		cout << stack[i] << "|";
	}
	cout << endl;
	delete[] stack;
	return top + 1;
}

int main(int argc, char* argv[]) {
	//int arr[] = {6,3,7,11,12,10,1,13,8,5,4,15,14,9,2};
	int arr[] = {1, 1, 1, 2, 2, 2, 3, 3, 3};
	int len = sizeof(arr) / sizeof(int);
	cout << len << endl;
	cout << lis_dp(arr, len) << endl;
	cout << lis_greedy(arr, len) << endl;
	return 0;
}
/* 第一组测试数据
15
6|7|11|12|13|15|
6
1|2|8|9|13|14|
6
*/
从测试结果看出,虽然算法一和算法二给出的长度值相等,但是算法二给出的序列顺序与原来的不符。


参考:

http://www.cnblogs.com/zhtzhl/archive/2012/08/03/2622219.html

http://www.cnblogs.com/zhanglanyun/archive/2011/09/09/2172809.html

http://hi.baidu.com/rffffffff007/item/75353d0c77192810addc70b6

热心网友 时间:2022-04-12 15:58

1.相对于递归算法,递推算法免除了数据进出栈的过程,也就是说,不需要函数不断的向边界值靠拢,而直接从边界出发,直到求出函数值.
比如阶乘函数:f(n)=n*f(n-1)
在f(3)的运算过程中,递归的数据流动过程如下:
f(3){f(i)=f(i-1)*i}-->f(2)-->f(1)-->f(0){f(0)=1}-->f(1)-->f(2)--f(3){f(3)=6}
而递推如下:
f(0)-->f(1)-->f(2)-->f(3)
由此可见,递推的效率要高一些,在可能的情况下应尽量使用递推.但是递归作为比较基础的算法,它的作用不能忽视.所以,在把握这两种算法的时候应该特别注意.
2.所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作。
分类
在计算机科学所使用的排序算法通常被分类为:
计算的复杂度(最差、平均、和最好表现),依据串列(list)的大小(n)。一般而言,好的表现是O。(n log n),且坏的行为是Ω(n2)。对於一个排序理想的表现是O(n)。仅使用一个抽象关键比较运算的排序算法总平均上总是至少需要Ω(n log n)。
记忆体使用量(以及其他电脑资源的使用)
稳定度:稳定排序算法会依照相等的关键(换言之就是值)维持纪录的相对次序。也就是一个排序算法是稳定的,就是当有两个有相等关键的纪录R和S,且在原本的串列中R出现在S之前,在排序过的串列中R也将会是在S之前。
一般的方法:插入、交换、选择、合并等等。交换排序包含冒泡排序(bubble sort)和快速排序(quicksort)。选择排序包含shaker排序和堆排序(heapsort)。
当相等的元素是无法分辨的,比如像是整数,稳定度并不是一个问题。然而,假设以下的数对将要以他们的第一个数字来排序。
(4, 1) (3, 1) (3, 7) (5, 6)
在这个状况下,有可能产生两种不同的结果,一个是依照相等的键值维持相对的次序,而另外一个则没有:
(3, 1) (3, 7) (4, 1) (5, 6) (维持次序)
(3, 7) (3, 1) (4, 1) (5, 6) (次序被改变)
不稳定排序算法可能会在相等的键值中改变纪录的相对次序,但是稳定排序算法从来不会如此。不稳定排序算法可以被特别地时作为稳定。作这件事情的一个方式是人工扩充键值的比较,如此在其他方面相同键值的两个物件间之比较,就会被决定使用在原先资料次序中的条目,当作一个同分决赛。然而,要记住这种次序通常牵涉到额外的空间负担。
排列算法列表
在这个表格中,n是要被排序的纪录数量以及k是不同键值的数量。
稳定的
冒泡排序(bubble sort) — O(n2)
鸡尾酒排序 (Cocktail sort, 双向的冒泡排序) — O(n2)
插入排序 (insertion sort)— O(n2)
桶排序 (bucket sort)— O(n); 需要 O(k) 额外 记忆体
计数排序 (counting sort) — O(n+k); 需要 O(n+k) 额外 记忆体
归并排序 (merge sort)— O(n log n); 需要 O(n) 额外记忆体
原地归并排序 — O(n2)
二叉树排序 (Binary tree sort) — O(n log n); 需要 O(n) 额外记忆体
鸽巢排序 (Pigeonhole sort) — O(n+k); 需要 O(k) 额外记忆体
基数排序 (radix sort)— O(n·k); 需要 O(n) 额外记忆体
Gnome sort — O(n2)
Library sort — O(n log n) with high probability, 需要 (1+ε)n 额外记忆体
不稳定
选择排序 (selection sort)— O(n2)
希尔排序 (shell sort)— O(n log n) 如果使用最佳的现在版本
Comb sort — O(n log n)
堆排序 (heapsort)— O(n log n)
Smoothsort — O(n log n)
快速排序 (quicksort)— O(n log n) 期望时间, O(n2) 最坏情况; 对於大的、乱数串列一般相信是最快的已知排序
Introsort — O(n log n)
Patience sorting — O(n log n + k) 最外情况时间, 需要 额外的 O(n + k) 空间, 也需要找到最长的递增子序列(longest increasing subsequence)
不实用的排序算法
Bogo排序 — O(n × n!) 期望时间, 无穷的最坏情况。
Stupid sort — O(n3); 递回版本需要 O(n2) 额外记忆体
Bead sort — O(n) or O(√n), 但需要特别的硬体
Pancake sorting — O(n), 但需要特别的硬体
排序的算法
排序的算法有很多,对空间的要求及其时间效率也不尽相同。下面列出了一些常见的排序算法。这里面插入排序和冒泡排序又被称作简单排序,他们对空间的要求不高,但是时间效率却不稳定;而后面三种排序相对于简单排序对空间的要求稍高一点,但时间效率却能稳定在很高的水平。基数排序是针对关键字在一个较小范围内的排序算法。
插入排序
冒泡排序
选择排序
快速排序
堆排序
归并排序
基数排序
希尔排序
插入排序
插入排序是这样实现的:
首先新建一个空列表,用于保存已排序的有序数列(我们称之为"有序列表")。
从原数列中取出一个数,将其插入"有序列表"中,使其仍旧保持有序状态。
重复2号步骤,直至原数列为空。
插入排序的平均时间复杂度为平方级的,效率不高,但是容易实现。它借助了"逐步扩大成果"的思想,使有序列表的长度逐渐增加,直至其长度等于原列表的长度。
冒泡排序
冒泡排序是这样实现的:
首先将所有待排序的数字放入工作列表中。
从列表的第一个数字到倒数第二个数字,逐个检查:若某一位上的数字大于他的下一位,则将它与它的下一位交换。
重复2号步骤,直至再也不能交换。
冒泡排序的平均时间复杂度与插入排序相同,也是平方级的,但也是非常容易实现的算法。
选择排序
选择排序是这样实现的:
设数组内存放了n个待排数字,数组下标从1开始,到n结束。
i=1
从数组的第i个元素开始到第n个元素,寻找最小的元素。
将上一步找到的最小元素和第i位元素交换。
如果i=n-1算法结束,否则回到第3步
选择排序的平均时间复杂度也是O(n²)的。
快速排序
现在开始,我们要接触高效排序算法了。实践证明,快速排序是所有排序算法中最高效的一种。它采用了分治的思想:先保证列表的前半部分都小于后半部分,然后分别对前半部分和后半部分排序,这样整个列表就有序了。这是一种先进的思想,也是它高效的原因。因为在排序算法中,算法的高效与否与列表中数字间的比较次数有直接的关系,而"保证列表的前半部分都小于后半部分"就使得前半部分的任何一个数从此以后都不再跟后半部分的数进行比较了,大大减少了数字间不必要的比较。但查找数据得另当别论了。
堆排序
堆排序与前面的算法都不同,它是这样的:
首先新建一个空列表,作用与插入排序中的"有序列表"相同。
找到数列中最大的数字,将其加在"有序列表"的末尾,并将其从原数列中删除。
重复2号步骤,直至原数列为空。
堆排序的平均时间复杂度为nlogn,效率高(因为有堆这种数据结构以及它奇妙的特征,使得"找到数列中最大的数字"这样的操作只需要O(1)的时间复杂度,维护需要logn的时间复杂度),但是实现相对复杂(可以说是这里7种算法中比较难实现的)。
看起来似乎堆排序与插入排序有些相像,但他们其实是本质不同的算法。至少,他们的时间复杂度差了一个数量级,一个是平方级的,一个是对数级的。
平均时间复杂度
插入排序 O(n2)
冒泡排序 O(n2)
选择排序 O(n2)
快速排序 O(n log n)
堆排序 O(n log n)
归并排序 O(n log n)
基数排序 O(n)
希尔排序 O(n1.25)
3.索引查找是在索引表和主表(即线性表的索引存储结构)上进行的查找。索引查找的过程是:首先根据给定的索引值K1,在索引表上查找出索引值等于KI的索引项,以确定对应予表在主表中的开始位置和长度,然后再根据给定的关键字K2,茬对应的子表中查找出关键字等于K2的元素(结点)。对索引表或子表进行查找时,若表是顺序存储的有序表,则既可进行顺序查找,也可进行二分查找,否则只能进行顺序查找。
设数组A是具有mainlist类型的一个主表,数组B是具有inde)dist类型的在主表A 上建立的一个索引表,m为索引表B的实际长度,即所含的索引项的个数,KI和K2分别为给定待查找的索引值和关键字(当然它们的类型应分别为索引表中索引值域的类型和主表中关键字域在索引存储中,不仅便于查找单个元素,而且更便于查找一个子表中的全部元素。当需要对一个子袁中的全部元素依次处理时,只要从索引表中查找出该子表的开始位
置即可。由此开始位置可以依次取出该子表中的每一个元素,所以整个查找过程的时间复杂度为,若不是采用索引存储,而是采用顺序存储,即使把它组织成有序表而进行二分查找时,索引查找一个子表中的所有元素与二分查找一个子表中的所有元素相比。
若在主表中的每个子表后都预留有空闲位置,则索引存储也便于进行插入和删除运算,因为其运算过程只涉及到索引表和相应的子表,只需要对相应子表中的元素进行比较和移动,与其它任何子表无关,不像顺序表那样需涉及到整个表中的所有元素,即牵一发而动全身。
在线性表的索引存储结构上进行插入和删除运算的算法,也同查找算法类似,其过程为:首先根据待插入或删除元素的某个域(假定子表就是按照此域的值划分的)的值查找索引表,确定出对应的子表,然后再根据待插入或删除元素的关键字,在该子表中做插入或删除元素的操作。因为每个子表不是顺序存储,就是链接存储,所以对它们做插入或删除操作都是很简单的。
4.插入法排序
#define N 10
#include"stdio.h"
main()
{ int i,j,k,t,a[N];
clrscr();
printf("Please input %d numbers:\n",N);
for(i=0;i<N;i++)
scanf("%d",&a[i]);
for(i=1;i<N;i++)
{
for(j=0;j<i;j++)
{if(a[j]>a[i])
{t=a[i];
for(k=i;k>=j;k--)
a[k]=a[k-1];
a[j]=t;
}
}
}
printf("small to big order:\n");
for(i=0;i<N;i++)
printf("%-2d",a[i]);
printf("\n");
getch();
}

热心网友 时间:2022-04-12 17:16

2.举冒泡排序法为例
#include <stdio.h>

void sort(int *s, int n)
{
int i, j, t;
for(i = 1; i != n; ++i)
for(j = 0; j != n - i; ++j)
if(s[j] > s[j + 1])
{
t = s[j];
s[j] = s[j + 1];
s[j + 1] = t;
}
}

int main(int argc, char *argv[])
{
int s[10] = {9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, i;
sort(s, 10);
for(i = 0; i != 10; ++i)
printf("%2d", s[i]);
printf("\n");
return 0;
}
3.举二分查找法为例
#include <stdio.h>

int binarySearch(int *s, int n, int x)
{
int low = 0, high = n - 1;
while(low <= high)
{
int mid = (low + high) / 2;
if(s[mid] < x)
{ low = mid + 1; }
else if(s[mid] > x)
{ high = mid - 1; }
else
{ return mid; }
}
return -1;
}

int main(int argc, char *argv[])
{
int s[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
printf("%d\n",binarySearch(s, 10, 7) );
return 0;
}
5.欧几里得算法求最大公约数
#include <stdio.h>

int *(int m, int n)
{
int rem;
while(n != 0)
{
rem = m % n;
m = n;
n = rem;
}
return m;
}

int main(int argc, char *argv[])
{
printf("%d\n",*(128, 256));
return 0;
}

热心网友 时间:2022-04-12 18:50

/*冒泡排序(buddle sort)*/
main()
{
int a[11];
int i,j,t;
clrscr();
printf("input 10 numbers :\n");
for(i=1;i<11;i++)
scanf("%d",&a[i]);
printf("\n");
for(j=1;j<=9;j++)
for(i=1;i<=10-j;i++)
if(a[i]>a[i+1])
{t=a[i];a[i]=a[i+1];a[i+1]=t;}
printf("the sorted numbers:\n");
for(i=1;i<11;i++)
printf("%d ",a[i]);
getch();
}
/*选择排序(select sort)*/
#include<stdio.h>
main()
{
int num[10];int i,j,temp;
printf("Please input 10 numbers:\n");
for(i=0;i<10;i++) scanf("%d",&num[i]);
for(i=0;i<10;i++)
for(j=i;j<10;j++)
if(num[j]<num[i])
{temp=num[i];
num[i]=num[j];
num[j]=temp;
}
printf("The sorted numbers:\n");
for(i=0;i<10;i++)
printf("%4d",num[i]);
}

/*插入法排序*/
#define N 10
#include"stdio.h"
main()
{ int i,j,k,t,a[N];
clrscr();
printf("Please input %d numbers:\n",N);
for(i=0;i<N;i++)
scanf("%d",&a[i]);
for(i=1;i<N;i++)
{
for(j=0;j<i;j++)
{if(a[j]>a[i])
{t=a[i];
for(k=i;k>=j;k--)
a[k]=a[k-1];
a[j]=t;
}
}
}
printf("small to big order:\n");
for(i=0;i<N;i++)
printf("%-2d",a[i]);
printf("\n");
getch();
}

热心网友 时间:2022-04-12 20:42

你可以到网上搜一本叫《C语言常用算法程序集》的电子书,有附带程序

热心网友 时间:2022-04-12 22:50

你去买本《算法艺术与信息学竞赛》书吧,有你想要的算法。

热心网友 时间:2022-04-13 01:14

我有点参考资料 需要的话可以传给你 基本上有你需要的例程 可以留邮箱给我

热心网友 时间:2022-04-13 03:56

真不知道你要这些干什么……拿去研究,还是交作业……
这些还是要自己看的,算法,很基础,很重要,一定要自己解决的……

热心网友 时间:2022-04-13 06:54

你把问题分开,会容易的多。。。
这么多,谁高兴去找啊

热心网友 时间:2022-04-13 10:08

我有,怎么给你,给个QQ或E-mail
61520540

热心网友 时间:2022-04-13 13:40

咯咯希望你可以找到.

热心网友 时间:2022-04-13 17:28

好麻烦 你不如买书
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
苹果电脑电池充不进电苹果电脑充不进去电是怎么回事 苹果电脑不充电没反应苹果电脑充电指示灯不亮充不了电怎么办 狗狗更加忠诚护家、善解人意,养一只宠物陪伴自己,泰迪能长多大... 描写泰迪狗的外形和特点的句子 国外留学有用吗 花钱出国留学有用吗 !这叫什么号 百万医疗赔付后是否可以续保 前一年理赔过医疗险还能续保吗? 医疗住院险理赔后还能购买吗? word怎么清除底版颜色 一直连不上家里的Wifi “完璧归赵”典故是什么时期? 深圳市沙井新宝益股份合作公司怎么样? 苏州桃花坞在那里?有什么好玩的地方? 完璧归赵是谁? 请问义乌桃花坞桃花什么时候开,详细地址在哪里?我的导航地图怎么搜索不到? 盛新锂能业绩暴增?盛新锂能股价被调低?盛新锂能跌得太厉害? 请问各位前辈有在深圳古瑞瓦特新能源股份有限公司工作过或者面试过的没,有的话给点建议? 《烟雨江湖》的桃花坞怎么触发? 桃花坞综艺 哪个平台? 义乌桃花坞什么时候去最好? 盛新锂能股票值得购买吗 完璧归赵是历史哪一位人物的故事 桃花坞开放大巴车有停车吗 盛新锂能股票牛叉查询 盛新锂能能成为牛股吗 义乌上溪桃花坞的桃花今年什么时候会开啊 笔记本win7系统窗口最大化时只显示一半怎么办 2021盛新锂能股分红 PP奶瓶和PPSU奶瓶的区别 ppsu和pp哪个好 电脑WiFi老是显示无法找到网络,怎么办? 电脑的wifi找不到网络怎么办?急啊急啊急啊,好急啊,快点告诉我吧! 电脑wifi找不到网络怎么办 电脑为什么连接wifi显示无网络连接 请问谁有1984电影的资源? 1984电影迅雷下载地址 Ic插座 的作用? 跪求1984改编电影,【在线观看】免费百度云资源 IC引脚插座内部的结构图,或者说它对应的功能是什么 一九八四的影片评价 8脚的底座如何插6脚的芯片 《神奇女侠1984》在中国大陆票房扑街,中国人不喜欢看美国大片了吗? IC RX-2B DIP怎么安装? 电路中使用ic插座的好处与缺点, 求1984年版电影《雷雨》的下载地址 求1984电影! IC插座具备哪些优点? 求电影《1984》的下载电影