手机站
网通分站
电信主站
密 码:
用户名:
当前位置 : 主页>程序设计>C/C++>列表

C 程式设计例解(04)

来源:互联网 作者:west263.com 时间:2008-02-23
西部数码-全国虚拟主机10强!40余项虚拟主机管理功能,全国领先!双线多线虚拟主机南北访问畅通无阻!免费赠送企业邮局,.CN域名,自助建站480元起,免费试用7天,满意再付款! P4主机租用799元/月.月付免压金!
04. 试从含有n个int型数的数组中删去若干个成分,使剩下的全部成分构成一个不减的子序列。设计算法和编写程式求出数组的不减子序列的长。
解:
从数组的第一个元素开始,顺序考察数组的每个元素,当数组的全部元素都被考察后才能求出数组的最长不减子序列的长。设数组为b[],已考察了b[0]至b[i-1]的全部元素,求得当前最长的不减子序列长为k。当前正要考察b[i]是否会引起k值增大,依赖于b[i]是否会大于或等于b[0]至b[i-1]中某个最长不减子序列的终元素.b[0]至b[i-1]中可能有多个长为k的不减子序列。很显然,在同样长度的不减子序列中,只要保留那个子序列终元素最小的一个就足够了。如有一变量保存有在b[0]至b[i-1]中长度为k的不减子序列最小的终元素,这样在b[0]至b[i-1]中,是否有长度为k 1的不减子序列,依赖于b[i]是否大于等于那个长度为k的不减子序列的终元素值。
但当b[i]小于那个长度为k的不减子序列最小的终元素的值时,假如在b[0]至b[i-1]中有长度为k-1的不减子序列,且该子序列的值不大于b[i],这时因长度为k-1的不减子序列的终元素值小于等于b[i],就得到一个终元素更小的长度为k的不减子序列。为能发现上述可能,就得保留长度为k-1的不减子序列的终元素。依此类推,为保留长为k-2,k-3等的不减子序列,相应地也要为他们保留终元素的值。为此要引入一个数组变量,设为数组a[],其第j个元素a[j]存放长为j的不减子序列的终元素的值。显然,数组a[]中的元素也是不减的序列。利用这个性质,在考察b[i]时,就能知道a[]中哪个元素需要改变。从最长子序列至最短子序列顺序寻找终元素小于等于b[i]的长为j的子序列,因b[i]大于等于长为j的不减子序列的终元素,找到了一个终元素更小的长为j 1的不减子序列,用b[i]作长为j 1的子序列的终止元素。当j的值为k 时,已为长为k 1的子序列设定了终元素,这时最长不减子序列长k应增1。通过以上分析,得到求最长不减子序列长的算法如下:
算法---求数组b[]的最长不减子序列长
{
置最长不减子序列长k为1;
用b[0]配置长为1的子序列的终止元素;
for(i=1;i<n;i ) /*顺序至b[1]考察至b[n-1]*/
{
以子序列长为k至1的顺序寻找其终元素小于等于b[i]的长为j的子序列;
用b[i]作为长为j 1的子序列的终元素;
if(j==k)k ; /*最长不减子序列长k增1*/
}
}
程式代码如下:
#include<stdio.h>
#define N 100
int b[]={9,8,5,4,3,2,7,6,8,7,5,3,4,5,9,1};
int a[N];
#define n sizeof b/sizeof b[0]
void main()
{
int k,i,j;
a[1]=b[0];
k=1;
for(i=1;i<n;i )
{
for(j=k;j>=1&&a[j]>b[i];j--);
a[j 1]=b[i]; /*长为j 1的子序列的终元素存贮在a[j 1]*/
if(j==k) k ; /*最长不减子序列长k增1*/
}
printf("K = %d\n",k);
}

程式运行结果如下:
k = 5
------------------
若把本问题改为求从数组中删去部分元素后的最长不减子序列,就要在求最长不减子序列长的过程中,不但要保留各种长度不减子序列的终元素,同时要保留不减子序列的全部元素。为此,上述程式中的数组a[]应改为两维数组a[][],其中a[][]的j行存储长为不减子序列的元素,该子序列的终元素为a[j][j-1]。在找到一个终元素更小的长为j 1的不减子序列时,除用b[i]作为j 1的子序旬的终止元素外,应同时将长为j的子序列元素全部复制到长为j 1的子序列中。直接写出程式如下:
#include<stdio.h>
#define N 100
int b[] = {9,8,5,4,3,2,7,6,8,7,5,3,4,5,9,1};
int a[N][N];
#define n sizeof b/sizeof b[0]
void main()
{
int k,i,j,m;
a[1][0]=b[0];
k=1;
for(i=1;i<n;i )
{
for(j=k;j>=1&&a[j][j-1]>b[i];j--);
for(m=0;m<j;m ) /*长为j的子序列复制到长为j 1的子序列*/
a[j 1][m]=a[j][m];
a[j 1][j]=b[i]; /*长为j 1的终元素存贮在a[j 1][j]*/
if(j==k) k ; /*最长不减子序列长k增1*/
}
printf("K = %d\n",k);
for(j=0;j<k;j )
printf("M",a[k][j]);
printf("\n");
}
程式运行结果如下:
k=5
2 3 4 5 9



文章整理:西部数码--专业提供域名注册虚拟主机服务
http://www.west263.com
以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

热点关注
IDC资讯 虚拟主机 域名注册 托管租用 vps主机 智能建站
网站运营 建站经验 策划盈利 搜索优化 网站推广 免费资源
网站联盟 联盟新闻 联盟介绍 联盟点评 网赚技巧
行业资讯 业界动态 搜索引擎 网络游戏 门户动态 电子商务 广告传媒
网络编程 Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术 Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷 Internet Explorer
网页制作 FrontPages Dreamweaver Javascript css photoshop fireworks Flash
程序设计 Java技术 C/C++ VB delphi
网络知识 网络协议 网络安全 网络管理 组网方案 Cisco技术
操作系统 Win2000 WinXP Win2003 Mac OS Linux FreeBSD
返回首页 |关于我们 | 联系我们 | 付款方式 | 创业联盟 | 价格总览 | 资讯中心 | 友情链接 | 网站地图 | 招贤纳士 | RSS