当前位置:首页 » 编程语言 » 最长递增子序列c语言
扩展阅读
webinf下怎么引入js 2023-08-31 21:54:13
堡垒机怎么打开web 2023-08-31 21:54:11

最长递增子序列c语言

发布时间: 2022-01-24 03:11:17

1. c语言排序

//总共给你整理了7种排序算法:希尔排序,链式基数排序,归并排序
//起泡排序,简单选择排序,树形选择排序,堆排序,先自己看看吧,
//看不懂可以再问身边的人或者查资料,既然可以上网,我相信你所在的地方信息流通方式应该还行,所有的程序全部在VC++6.0下编译通过
//希尔排序
#include<stdio.h>
typedef int InfoType; // 定义其它数据项的类型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};

struct SqList // 顺序表类型
{
RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
};
void ShellInsert(SqList &L,int dk)
{ // 对顺序表L作一趟希尔插入排序。本算法是和一趟直接插入排序相比,
// 作了以下修改:
// 1.前后记录位置的增量是dk,而不是1;
// 2.r[0]只是暂存单元,不是哨兵。当j<=0时,插入位置已找到。算法10.4
int i,j;
for(i=dk+1;i<=L.length;++i)
if LT(L.r[i].key,L.r[i-dk].key)
{ // 需将L.r[i]插入有序增量子表
L.r[0]=L.r[i]; // 暂存在L.r[0]
for(j=i-dk;j>0&<(L.r[0].key,L.r[j].key);j-=dk)
L.r[j+dk]=L.r[j]; // 记录后移,查找插入位置
L.r[j+dk]=L.r[0]; // 插入
}
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("%d ",L.r[i].key);
printf("\n");
}

void print1(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

void ShellSort(SqList &L,int dlta[],int t)
{ // 按增量序列dlta[0..t-1]对顺序表L作希尔排序。算法10.5
int k;
for(k=0;k<t;++k)
{
ShellInsert(L,dlta[k]); // 一趟增量为dlta[k]的插入排序
printf("第%d趟排序结果: ",k+1);
print(L);
}
}

#define N 10
#define T 3
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8},{55,9},{4,10}};
SqList l;
int dt[T]={5,3,1}; // 增量序列数组
for(int i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前: ");
print(l);
ShellSort(l,dt,T);
printf("排序后: ");
print1(l);
}

/*****************************************************************/
//链式基数排序
typedef int InfoType; // 定义其它数据项的类型
typedef int KeyType; // 定义RedType类型的关键字为整型
struct RedType // 记录类型(同c10-1.h)
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项
};
typedef char KeysType; // 定义关键字类型为字符型
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
#define MAX_NUM_OF_KEY 8 // 关键字项数的最大值
#define RADIX 10 // 关键字基数,此时是十进制整数的基数
#define MAX_SPACE 1000
struct SLCell // 静态链表的结点类型
{
KeysType keys[MAX_NUM_OF_KEY]; // 关键字
InfoType otheritems; // 其它数据项
int next;
};

struct SLList // 静态链表类型
{
SLCell r[MAX_SPACE]; // 静态链表的可利用空间,r[0]为头结点
int keynum; // 记录的当前关键字个数
int recnum; // 静态链表的当前长度
};

typedef int ArrType[RADIX];
void InitList(SLList &L,RedType D[],int n)
{ // 初始化静态链表L(把数组D中的数据存于L中)
char c[MAX_NUM_OF_KEY],c1[MAX_NUM_OF_KEY];
int i,j,max=D[0].key; // max为关键字的最大值
for(i=1;i<n;i++)
if(max<D[i].key)
max=D[i].key;
L.keynum=int(ceil(log10(max)));
L.recnum=n;
for(i=1;i<=n;i++)
{
L.r[i].otheritems=D[i-1].otherinfo;
itoa(D[i-1].key,c,10); // 将10进制整型转化为字符型,存入c
for(j=strlen(c);j<L.keynum;j++) // 若c的长度<max的位数,在c前补'0'
{
strcpy(c1,"0");
strcat(c1,c);
strcpy(c,c1);
}
for(j=0;j<L.keynum;j++)
L.r[i].keys[j]=c[L.keynum-1-j];
}
}

int ord(char c)
{ // 返回k的映射(个位整数)
return c-'0';
}

void Distribute(SLCell r[],int i,ArrType f,ArrType e) // 算法10.15
{ // 静态键表L的r域中记录已按(keys[0],…,keys[i-1])有序。本算法按
// 第i个关键字keys[i]建立RADIX个子表,使同一子表中记录的keys[i]相同。
// f[0..RADIX-1]和e[0..RADIX-1]分别指向各子表中第一个和最后一个记录
int j,p;
for(j=0;j<RADIX;++j)
f[j]=0; // 各子表初始化为空表
for(p=r[0].next;p;p=r[p].next)
{
j=ord(r[p].keys[i]); // ord将记录中第i个关键字映射到[0..RADIX-1]
if(!f[j])
f[j]=p;
else
r[e[j]].next=p;
e[j]=p; // 将p所指的结点插入第j个子表中
}
}

int succ(int i)
{ // 求后继函数
return ++i;
}

void Collect(SLCell r[],ArrType f,ArrType e)
{ // 本算法按keys[i]自小至大地将f[0..RADIX-1]所指各子表依次链接成
// 一个链表,e[0..RADIX-1]为各子表的尾指针。算法10.16
int j,t;
for(j=0;!f[j];j=succ(j)); // 找第一个非空子表,succ为求后继函数
r[0].next=f[j];
t=e[j]; // r[0].next指向第一个非空子表中第一个结点
while(j<RADIX-1)
{
for(j=succ(j);j<RADIX-1&&!f[j];j=succ(j)); // 找下一个非空子表
if(f[j])
{ // 链接两个非空子表
r[t].next=f[j];
t=e[j];
}
}
r[t].next=0; // t指向最后一个非空子表中的最后一个结点
}

void printl(SLList L)
{ // 按链表输出静态链表
int i=L.r[0].next,j;
while(i)
{
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf(" ");
i=L.r[i].next;
}
}

void RadixSort(SLList &L)
{ // L是采用静态链表表示的顺序表。对L作基数排序,使得L成为按关键字
// 自小到大的有序静态链表,L.r[0]为头结点。算法10.17
int i;
ArrType f,e;
for(i=0;i<L.recnum;++i)
L.r[i].next=i+1;
L.r[L.recnum].next=0; // 将L改造为静态链表
for(i=0;i<L.keynum;++i)
{ // 按最低位优先依次对各关键字进行分配和收集
Distribute(L.r,i,f,e); // 第i趟分配
Collect(L.r,f,e); // 第i趟收集
printf("第%d趟收集后:\n",i+1);
printl(L);
printf("\n");
}
}

void print(SLList L)
{ // 按数组序号输出静态链表
int i,j;
printf("keynum=%d recnum=%d\n",L.keynum,L.recnum);
for(i=1;i<=L.recnum;i++)
{
printf("keys=");
for(j=L.keynum-1;j>=0;j--)
printf("%c",L.r[i].keys[j]);
printf(" otheritems=%d next=%d\n",L.r[i].otheritems,L.r[i].next);
}
}

void Sort(SLList L,int adr[]) // 改此句(类型)
{ // 求得adr[1..L.length],adr[i]为静态链表L的第i个最小记录的序号
int i=1,p=L.r[0].next;
while(p)
{
adr[i++]=p;
p=L.r[p].next;
}
}

void Rearrange(SLList &L,int adr[]) // 改此句(类型)
{ // adr给出静态链表L的有序次序,即L.r[adr[i]]是第i小的记录。
// 本算法按adr重排L.r,使其有序。算法10.18(L的类型有变)
int i,j,k;
for(i=1;i<L.recnum;++i) // 改此句(类型)
if(adr[i]!=i)
{
j=i;
L.r[0]=L.r[i]; // 暂存记录L.r[i]
while(adr[j]!=i)
{ // 调整L.r[adr[j]]的记录到位直到adr[j]=i为止
k=adr[j];
L.r[j]=L.r[k];
adr[j]=j;
j=k; // 记录按序到位
}
L.r[j]=L.r[0];
adr[j]=j;
}
}

#define N 10
void main()
{
RedType d[N]={{278,1},{109,2},{63,3},{930,4},{589,5},{184,6},{505,7},{269,8},{8,9},{83,10}};
SLList l;
int *adr;
InitList(l,d,N);
printf("排序前(next域还没赋值):\n");
print(l);
RadixSort(l);
printf("排序后(静态链表):\n");
print(l);
adr=(int*)malloc((l.recnum)*sizeof(int));
Sort(l,adr);
Rearrange(l,adr);
printf("排序后(重排记录):\n");
print(l);
}
/*******************************************/
//归并排序
#include<stdio.h>
typedef int InfoType; // 定义其它数据项的类型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};

struct SqList // 顺序表类型
{
RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
};
void Merge(RedType SR[],RedType TR[],int i,int m,int n)
{ // 将有序的SR[i..m]和SR[m+1..n]归并为有序的TR[i..n] 算法10.12
int j,k,l;
for(j=m+1,k=i;i<=m&&j<=n;++k) // 将SR中记录由小到大地并入TR
if LQ(SR[i].key,SR[j].key)
TR[k]=SR[i++];
else
TR[k]=SR[j++];
if(i<=m)
for(l=0;l<=m-i;l++)
TR[k+l]=SR[i+l]; // 将剩余的SR[i..m]复制到TR
if(j<=n)
for(l=0;l<=n-j;l++)
TR[k+l]=SR[j+l]; // 将剩余的SR[j..n]复制到TR
}

void MSort(RedType SR[],RedType TR1[],int s, int t)
{ // 将SR[s..t]归并排序为TR1[s..t]。算法10.13
int m;
RedType TR2[MAXSIZE+1];
if(s==t)
TR1[s]=SR[s];
else
{
m=(s+t)/2; // 将SR[s..t]平分为SR[s..m]和SR[m+1..t]
MSort(SR,TR2,s,m); // 递归地将SR[s..m]归并为有序的TR2[s..m]
MSort(SR,TR2,m+1,t); // 递归地将SR[m+1..t]归并为有序的TR2[m+1..t]
Merge(TR2,TR1,s,m,t); // 将TR2[s..m]和TR2[m+1..t]归并到TR1[s..t]
}
}

void MergeSort(SqList &L)
{ // 对顺序表L作归并排序。算法10.14
MSort(L.r,L.r,1,L.length);
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 7
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
MergeSort(l);
printf("排序后:\n");
print(l);
}
/**********************************************/
//起泡排序
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status;
typedef int Boolean;
#define N 8
void bubble_sort(int a[],int n)
{ // 将a中整数序列重新排列成自小至大有序的整数序列(起泡排序)
int i,j,t;
Status change;
for(i=n-1,change=TRUE;i>1&&change;--i)
{
change=FALSE;
for(j=0;j<i;++j)
if(a[j]>a[j+1])
{
t=a[j];
a[j]=a[j+1];
a[j+1]=t;
change=TRUE;
}
}
}

void print(int r[],int n)
{
int i;
for(i=0;i<n;i++)
printf("%d ",r[i]);
printf("\n");
}

void main()
{
int d[N]={49,38,65,97,76,13,27,49};
printf("排序前:\n");
print(d,N);
bubble_sort(d,N);
printf("排序后:\n");
print(d,N);
}
/****************************************************/
//简单选择排序
#include<stdio.h>
typedef int InfoType; // 定义其它数据项的类型
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};

struct SqList // 顺序表类型
{
RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
};
int SelectMinKey(SqList L,int i)
{ // 返回在L.r[i..L.length]中key最小的记录的序号
KeyType min;
int j,k;
k=i; // 设第i个为最小
min=L.r[i].key;
for(j=i+1;j<=L.length;j++)
if(L.r[j].key<min) // 找到更小的
{
k=j;
min=L.r[j].key;
}
return k;
}

void SelectSort(SqList &L)
{ // 对顺序表L作简单选择排序。算法10.9
int i,j;
RedType t;
for(i=1;i<L.length;++i)
{ // 选择第i小的记录,并交换到位
j=SelectMinKey(L,i); // 在L.r[i..L.length]中选择key最小的记录
if(i!=j)
{ // 与第i个记录交换
t=L.r[i];
L.r[i]=L.r[j];
L.r[j]=t;
}
}
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
SelectSort(l);
printf("排序后:\n");
print(l);
}
/************************************************/
//树形选择排序
#include<string.h>
#include<ctype.h>
#include<malloc.h> // malloc()等
#include<limits.h> // INT_MAX等
#include<stdio.h> // EOF(=^Z或F6),NULL
#include<stdlib.h> // atoi()
#include<io.h> // eof()
#include<math.h> // floor(),ceil(),abs()
#include<process.h> // exit()
#include<iostream.h> // cout,cin
// 函数结果状态代码
#define TRUE 1
#define FALSE 0
#define OK 1
#define ERROR 0
#define INFEASIBLE -1
typedef int Status; // Status是函数的类型,其值是函数结果状态代码,如OK等
typedef int Boolean; // Boolean是布尔类型,其值是TRUE或FALSE
typedef int InfoType; // 定义其它数据项的类型
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};

struct SqList // 顺序表类型
{
RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
};
void TreeSort(SqList &L)
{ // 树形选择排序
int i,j,j1,k,k1,l,n=L.length;
RedType *t;
l=(int)ceil(log(n)/log(2))+1; // 完全二叉树的层数
k=(int)pow(2,l)-1; // l层完全二叉树的结点总数
k1=(int)pow(2,l-1)-1; // l-1层完全二叉树的结点总数
t=(RedType*)malloc(k*sizeof(RedType)); // 二叉树采用顺序存储结构
for(i=1;i<=n;i++) // 将L.r赋给叶子结点
t[k1+i-1]=L.r[i];
for(i=k1+n;i<k;i++) // 给多余的叶子的关键字赋无穷大
t[i].key=INT_MAX;
j1=k1;
j=k;
while(j1)
{ // 给非叶子结点赋值
for(i=j1;i<j;i+=2)
t[i].key<t[i+1].key?(t[(i+1)/2-1]=t[i]):(t[(i+1)/2-1]=t[i+1]);
j=j1;
j1=(j1-1)/2;
}
for(i=0;i<n;i++)
{
L.r[i+1]=t[0]; // 将当前最小值赋给L.r[i]
j1=0;
for(j=1;j<l;j++) // 沿树根找结点t[0]在叶子中的序号j1
t[2*j1+1].key==t[j1].key?(j1=2*j1+1):(j1=2*j1+2);
t[j1].key=INT_MAX;
while(j1)
{
j1=(j1+1)/2-1; // 序号为j1的结点的双亲结点序号
t[2*j1+1].key<=t[2*j1+2].key?(t[j1]=t[2*j1+1]):(t[j1]=t[2*j1+2]);
}
}
free(t);
}

void print(SqList L)
{
int i;
for(i=1;i<=L.length;i++)
printf("(%d,%d)",L.r[i].key,L.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
SqList l;
int i;
for(i=0;i<N;i++)
l.r[i+1]=d[i];
l.length=N;
printf("排序前:\n");
print(l);
TreeSort(l);
printf("排序后:\n");
print(l);
}
/****************************/
//堆排序
#include<stdio.h>
typedef int InfoType; // 定义其它数据项的类型
#define EQ(a,b) ((a)==(b))
#define LT(a,b) ((a)<(b))
#define LQ(a,b) ((a)<=(b))
#define MAXSIZE 20 // 一个用作示例的小顺序表的最大长度
typedef int KeyType; // 定义关键字类型为整型
struct RedType // 记录类型
{
KeyType key; // 关键字项
InfoType otherinfo; // 其它数据项,具体类型在主程中定义
};

struct SqList // 顺序表类型
{
RedType r[MAXSIZE+1]; // r[0]闲置或用作哨兵单元
int length; // 顺序表长度
};

typedef SqList HeapType; // 堆采用顺序表存储表示
void HeapAdjust(HeapType &H,int s,int m) // 算法10.10
{ // 已知H.r[s..m]中记录的关键字除H.r[s].key之外均满足堆的定义,本函数
// 调整H.r[s]的关键字,使H.r[s..m]成为一个大顶堆(对其中记录的关键字而言)
RedType rc;
int j;
rc=H.r[s];
for(j=2*s;j<=m;j*=2)
{ // 沿key较大的孩子结点向下筛选
if(j<m&<(H.r[j].key,H.r[j+1].key))
++j; // j为key较大的记录的下标
if(!LT(rc.key,H.r[j].key))
break; // rc应插入在位置s上
H.r[s]=H.r[j];
s=j;
}
H.r[s]=rc; // 插入
}

void HeapSort(HeapType &H)
{ // 对顺序表H进行堆排序。算法10.11
RedType t;
int i;
for(i=H.length/2;i>0;--i) // 把H.r[1..H.length]建成大顶堆
HeapAdjust(H,i,H.length);
for(i=H.length;i>1;--i)
{ // 将堆顶记录和当前未经排序子序列H.r[1..i]中最后一个记录相互交换
t=H.r[1];
H.r[1]=H.r[i];
H.r[i]=t;
HeapAdjust(H,1,i-1); // 将H.r[1..i-1]重新调整为大顶堆
}
}

void print(HeapType H)
{
int i;
for(i=1;i<=H.length;i++)
printf("(%d,%d)",H.r[i].key,H.r[i].otherinfo);
printf("\n");
}

#define N 8
void main()
{
RedType d[N]={{49,1},{38,2},{65,3},{97,4},{76,5},{13,6},{27,7},{49,8}};
HeapType h;
int i;
for(i=0;i<N;i++)
h.r[i+1]=d[i];
h.length=N;
printf("排序前:\n");
print(h);
HeapSort(h);
printf("排序后:\n");
print(h);
}

2. C语言 拦截导弹

for (i=n-1;i>=1;i--)
{
for (j=n;j>=i+1;j--)
{
if (a[i]>a[j] && l[j]+1>l[i])
{
l[i]=l[j]+1;
}//printf("%d %d\n",i,j);}
max=0,ss=1;//for(i=1;i<=n;i++) printf("%d ",l[i]);printf("\n");
for (i=1;i<n;i++)
{

在这里有死循环,j永远小于i
---------------------------------------------------
/*
VC6.0编译运行成功
*/
#include
#include
/*
描述 Description
某国为了防御敌国的导弹袭击,研发出一种导弹拦截系统。但是这种导弹拦截系统有一个缺陷:虽然它的第一发炮弹能够到达任意的高度,但是以后每一发炮弹都不能高于前一发的高度。某天,雷达捕捉到敌国的导弹来袭。由于该系统还在试验阶段,所以只有一套系统,因此有可能不能拦截所有的导弹。
输入格式 Input Format
输入数据只有一行,该行包含若干个数据,之间用半角逗号隔开,表示导弹依次飞来的高度(导弹最多有 20 枚,其高度为不大于 30000 的正整数)。
输出格式 Output Format
输出数据只有一行,该行包含两个数据,之间用半角逗号隔开。第一个数据表示这套系统最多能拦截的导弹数;第二个数据表示若要拦截所有导弹至少要再添加多少套这样的系统。
样例输入 Sample Input
389,207,155,300,299,170,158,65
样例输出 Sample Output
6,1
其它测试输入样例
389,207,155,300,299,170,65,158
5,3,1,4,3,2,1,0
1,2,3,4,5,6,2
*/
/*
分析,问题是动态规划与Dilworth定理题目
http://www.gnocuil.cn/blog/article.asp?id=16
*/
int main()
{

char s[105];
int i, j, n, a[21], l[21], sign[21], max = 0, min = 0;
scanf("%s", s);
//min 代表最长递增序列长度 max 代表最短递减序列长度
for (i = 0, j = 0, a[0] = l[0] = sign[0] = 0; i < strlen(s); i++)
{

if (s[i] == ',')
{
a[++j] = 0;
sign[j] = 1;
l[j] = 1;

}
else
{
a[j] = a[j] * 10 + (s[i] - '0');
}
}
n = j;

for (i = n - 1; i >= 0; i--)
{
int maxflag = 0, minflag = 0;
j = i + 1;
while(j <= n)
{
if(a[i] > a[j])
{
if(l[i] < l[j])
{
l[i] = l[j];
}
maxflag = 1;
}
else if(a[i] < a[j])
{
if(sign[i] < sign[j])
{
sign[i] = sign[j];
}
minflag = 1;
}
j++;
}
if(maxflag)
l[i]++;

if(minflag)
sign[i]++;

if(max < l[i])
{
max = l[i];
}

if(min < sign[i])
{
min = sign[i];
}
}
printf("%d,%d\n", max, min - 1);
return (0);
}

3. C语言LCIS(最长公共上升子序列)(DP)如何打印解

用一个解向量存储解啊,思路如下
function(..., char v[]) /*v用于存储最优解的*/
{
......
if(当前解更优){
当前解为更优解;
更新向量v; /*最好附添加一个结束符*/
}
......
}

主函数中输出解向量即可。

4. 一道ACM的题目,求用C语言递归编写的算法,非常感谢啊!!!:求上升子序列和的最大值

您好!
这是杭电acm的第1087题,答案如下:
#include<stdio.h>
__int64 a[10009],sum[10009],Maxsum,max;
int main()
{
int i,j,n;
while(scanf("%d",&n),n!=0)
{
for(i=0;i<n;i++)
scanf("%I64d",&a[i]);
sum[0]=a[0];
for(i=1;i<n;i++)
{ Maxsum=0;
for(j=0;j<i;j++)
if(a[i]>a[j])
{
if(Maxsum<sum[j])
Maxsum=sum[j];
}

sum[i]=Maxsum+a[i];
}
max=sum[0];
for(i=1;i<n;i++)
if(max<sum[i])
max=sum[i];
printf("%I64d\n",max);

}
return 0;
}
希望对您有帮助!

5. 之前是一名ACMer,现在想做具体的项目,如新浪微博的应用,请问如何开始啊,我擅长C语言

一般要做到50行以内的程序不用调试、100行以内的二分钟内调试成功.

训练过ACM等程序设计竞赛的人在算法上有较大的优势,这就说明当你编程能力提高之后,主要时间是花在思考算法上,不是花在写程序与debug上。

下面给个计划你练练:

第一阶段:练经典常用算法,下面的每个算法给我打上十到二十遍,同时自己精简代码,因为太常用,所以要练到写时不用想,10-15分钟内打完,甚至关掉显示器都可以把程序打出来。
1.最短路(Floyd、Dijstra,BellmanFord)
2.最小生成树(先写个prim,kruscal要用并查集,不好写)
3.大数(高精度)加减乘除
4.二分查找. (代码可在五行以内)
5.叉乘、判线段相交、然后写个凸包.
6.BFS、DFS,同时熟练hash表(要熟,要灵活,代码要简)
7.数学上的有:辗转相除(两行内),线段交点、多角形面积公式.
8. 调用系统的qsort, 技巧很多,慢慢掌握.
9. 任意进制间的转换

第二阶段:练习复杂一点,但也较常用的算法。
如:
1. 二分图匹配(匈牙利),最小路径覆盖
2. 网络流,最小费用流。
3. 线段树.
4. 并查集。
5. 熟悉动态规划的各个典型:LCS、最长递增子串、三角剖分、记忆化dp
6.博弈类算法。博弈树,二进制法等。
7.最大团,最大独立集。
8.判断点在多边形内。
9. 差分约束系统.
10. 双向广度搜索、A*算法,最小耗散优先.

第三阶段:
前两个阶段是打基础,第三阶段是锻炼在比赛中可以快速建立模型、想新算法。这就要平时多做做综合的题型了。
1. 把oibh上的论文看看(大概几百篇的,我只看了一点点,呵呵)。
2. 平时扫扫zoj上的难题啦,别老做那些不用想的题.(中大acm的版主经常说我挑简单的来做:-P )
3. 多参加网上的比赛,感受一下比赛的气氛,评估自己的实力.
4. 一道题不要过了就算,问一下人,有更好的算法也打一下。
5. 做过的题要记好 :-)

ACMer必备知识(任重而道远......)

图论

路径问题
0/1边权最短路径
BFS
非负边权最短路径(Dijkstra)
可以用Dijkstra解决问题的特征
负边权最短路径
Bellman-Ford
Bellman-Ford的Yen-氏优化
差分约束系统
Floyd
广义路径问题
传递闭包
极小极大距离 / 极大极小距离
Euler Path / Tour
圈套圈算法
混合图的 Euler Path / Tour
Hamilton Path / Tour
特殊图的Hamilton Path / Tour 构造

生成树问题
最小生成树
第k小生成树
最优比率生成树
0/1分数规划
度限制生成树

连通性问题
强大的DFS算法
无向图连通性
割点
割边
二连通分支
有向图连通性
强连通分支
2-SAT
最小点基

有向无环图
拓扑排序
有向无环图与动态规划的关系

二分图匹配问题
一般图问题与二分图问题的转换思路
最大匹配
有向图的最小路径覆盖
0 / 1矩阵的最小覆盖
完备匹配
最优匹配
稳定婚姻

网络流问题
网络流模型的简单特征和与线性规划的关系
最大流最小割定理
最大流问题
有上下界的最大流问题
循环流
最小费用最大流 / 最大费用最大流

弦图的性质和判定

组合数学

解决组合数学问题时常用的思想
逼近
递推 / 动态规划
概率问题
Polya定理

计算几何 / 解析几何

计算几何的核心:叉积 / 面积
解析几何的主力:复数

基本形

直线,线段
多边形

凸多边形 / 凸包
凸包算法的引进,卷包裹法

Graham扫描法
水平序的引进,共线凸包的补丁

完美凸包算法

相关判定
两直线相交
两线段相交
点在任意多边形内的判定
点在凸多边形内的判定

经典问题
最小外接圆
近似O(n)的最小外接圆算法
点集直径
旋转卡壳,对踵点
多边形的三角剖分

数学 / 数论

最大公约数
Euclid算法
扩展的Euclid算法
同余方程 / 二元一次不定方程
同余方程组

线性方程组
高斯消元法
解mod 2域上的线性方程组
整系数方程组的精确解法

矩阵
行列式的计算
利用矩阵乘法快速计算递推关系

分数
分数树
连分数逼近

数论计算
求N的约数个数
求phi(N)
求约数和
快速数论变换
……

素数问题
概率判素算法
概率因子分解

数据结构

组织结构
二叉堆
左偏树
二项树
胜者树
跳跃表
样式图标
斜堆
reap

统计结构
树状数组
虚二叉树
线段树
矩形面积并
圆形面积并

关系结构
Hash表
并查集
路径压缩思想的应用

STL中的数据结构
vector
deque
set / map

动态规划 / 记忆化搜索

动态规划和记忆化搜索在思考方式上的区别

最长子序列系列问题
最长不下降子序列
最长公共子序列
最长公共不下降子序列

一类NP问题的动态规划解法

树型动态规划

背包问题

动态规划的优化
四边形不等式
函数的凸凹性
状态设计
规划方向

线性规划

常用思想

二分
最小表示法



KMP
Trie结构
后缀树/后缀数组
LCA/RMQ
有限状态自动机理论

排序
选择/冒泡
快速排序
堆排序
归并排序
基数排序
拓扑排序
排序网络

总的来说,ACM强调的是熟练掌握经典的数据结构和算法,要接解决的问题一般需要建模或转化成可用上述经典方法解决。与研究经常使用启发式策略、统计推断和预测、随机算法等思路不同,如果一个研究问题能被转化到一个上述的经典问题,往往看起来很苍白,这估计是研究与ACM的区别吧。

6. C语言,最长上升子序列数,,

最长上升子序列(LIS)
问题描述:设现在有一串序列,要求找出它的一串子序列,这串子序列可以不连续,但必须满足它是严格的单调递増的且为最长的。把这个长度输出。
示例:1 7 3 5 9 4 8 结果为4
题例:参看POJ 2533
解法:
1. DP之O(n2)算法:先按DP的思想来分析一下,要想求n个数的最长上升子序列,设有数据数组data[n]和状态数组dp[n],则对其尾元素data[n]来说,它的最长上升子序列就是它自己,即dp[n]=1,而当把它的前一个元素data[n-1]考虑进来时,如果data[n-1]<data[n]则会存在一个长度为2的上升子序列,如果data[n-1]>data[n]那么这个长度仍会是1。当把这个思想一般化的时候,对于任意一个元素data[k]来说,我们需要找出在data[k]以后的元素中比data[k]大,并且最长的一个序列做为它的后继。这样dp[k]就可以写成dp[k+1]+1。现在我们定义一个量dp[k]=m,它代表着到第k个元素为止(可以包含k也可以不包含k),它的最长上升序列的长度为m。仔细体会dp[k]=m的意义,这里面的k是可包括在内,也可以不包括在内的(与之前的最大子序列和不同)。要想确定这个m的值,就必须找到一个在第k个元素之前的一个元素的值小于data[k]的值,并且那个元素所对应的dp值是找到的满足第一个条件前提下dp值最大的一个。这就意味着我们需要内层遍历之前算出来的dp值,所以需要两层循环来实现这个算法。这样我们就可以总结出状态转移方程为dp[k]=max(dp[i](1<=i<=k&&a[i]<a[k])+1。其中找dp[i]的过程我们需要用一层循环来实现,而找dp[k]的过程也要一层循环,所以我们得到了O(n2)的算法。
dp[k]=max(dp[i])+1 其中i满足(1<=i<=k&&a[i]<a[k])
例程:
#include <stdio.h>
const int inf = -0x3fffffff;
int main(void)
{
int i,j,len,max,res,data[] = {1,7,3,5,9,4,8},dp[20]={1};
len = sizeof(data)/sizeof(int);
res = max = inf;
for(i=1;i<len;i++)
{
max = inf;
for(j=0;j<=i;j++)
if(data[i]>data[j]&&max<dp[j])
max=dp[j];
dp[i]=max+1;
if(res<dp[i])
res = dp[i];
}
printf("%d\n",res);
return 0;
}

7. 设计一个O(n的平方)时间的算法,找出由n个数组成的序列的最长单调递增子序列

用冒泡法 时间复杂度=O(n^2)
以 下是c语言版
#include <stdio.h>
main()
{int a[10];
int i,c,j;
for(i=0;i<10;i++)
{printf("请输入十个数,这是第%d个:",i+1);
scanf("%d",&a[i]);
}
for(i=0;i<10;i++)
{
for(j=10;j>i+1;j--)
{if(a[j-1]<a[j-2])
{c=a[j-1];
a[j-1]=a[j-2];
a[j-2]=c;
}
}
}
printf("从小到大的顺序是:");
for(i=0;i<10;i++)
{printf("\n%d",a[i]);
}
getch();
}

8. 求数组中的最长递增子序列的汇编写法。 要求:汇编,命令行,有输入输出,要输出长度和最长子序列。

这就是一个数列的问题吧,高中数学中有讲到的,找出数字的规律,然后推断出8086位上的数据到底是什么,不过-1 2 -3 4 -5 6 -7 到9之后,再是什么呢 从1开始 还是从0 还是什么呢,要把9之后的这个数字显示出来后,才能找到其规律,找不到规律就无从谈起八千之后的数字了。

9. c语言(高分)

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();
}

10. 谁帮忙做个C语言题目:最长上升下降子序列 在线等答案!!!

你是理工的吧
#include<stdio.h>
const int MAX=105;
int down[MAX],up[MAX];
int h[MAX],n;
void get_up()
{
int i,tmp,j;
for(i=0;i<n;i++)
{
tmp=1;
for(j=i-1;j>=0;j--)
{
if(h[i]>h[j]&&up[j]+1>tmp)
tmp=up[j]+1;
}
up[i]=tmp;
}
}
void get_down()
{
int i,j,tmp;
for(i=n-1;i>=0;i--)
{
tmp=1;
for(j=i+1;j<n;j++)
{
if(h[i]>h[j]&&down[j]+1>tmp)
tmp=down[j]+1;
}
down[i]=tmp;
}
}
int main()
{
int i,max;

while(scanf("%d",&n)!=EOF)
{
for(i=0;i<n;i++)
scanf("%d",&h[i]);
get_up();
get_down();
max=0;
for(i=0;i<n;i++)
{
if(up[i]+down[i]-1>max)
max=up[i]+down[i]-1;
}
printf("%d\n",n-max);
}
return 0;
}