若a(n-1)>a(n),则存在长度为的不下降序列。
③若从a(i)开始,此时最长不下降序列应该按下列方法求出:
在a(i+1),a(i+2),…,a(n)中,找出一个起始数据比a(i)大且最长的不下降序列,作为它的后续。
(2)数据结构设计
用数组b[i]记录点i到得最长的不下降子序列的长度,记录点i在最长的不下降子序列的后继续数据编号。
◎算法如下:
Intmaxn=100;
Inta[maxn],b[maxn],c[maxn];
Main()
{intn,I,j,max,p;
input(n);
for(i=1;i<=n;i=i+1)
{input(a[i]);
b[i]=1;
c[i]=0;}
For(i=n-1;i>=1;i=i-1)
{max=0;p=0;
for(j=i+1;j<=n;j=j+1)
if(a[i]max)
{max=b[j];p=j;}
if(p<>0)
{b[i]=b[p]+1;
c[i]=p;}
}
Max=0;p=0;
For(i=1;i<=n;i++)
if(b[i]>max)
{max=b[i];
p=I;}
Print(“maxlong=“,max);
Print(“resultis:
”);
While(p<>0)
{print(a[p]);
p=c[p];}
}
◎经过循环,数据的变化
a[1]=3;a[2]=18;a[3]=7
b[1]=1;b[2]=1;b[3]=1
c[1]=0;c[2]=0;c[3]=0
◎变化结果:
a[1]=3;a[2]=18;a[3]=7
b[1]=2;b[2]=1;b[3]=1
c[1]=2;c[2]=0;c[3]=0
4.礼物分配问题.两兄弟Alan和Bob,共同分配n个礼物.每个礼物只能分给其中的一个人,且不能分成两个.每个礼物i的价值为vi,为正整数.设a和b分别表示Alan和Bob所收到的礼物的总价值,V=
为所有礼物的总价值.为使两兄弟高兴,我们希望尽可能地均分这些礼物,即|a-b|打到最小。
◎分析:
该题目要求使得所分的礼物差值最小;
首先,我们知道礼物总价值为V=
;由于要使差值最小,则a与b要最接近于1/2V;故可以设a=1/2V+t,b=1/2V-t;故|a-b|=|(1/2V+t)-(1/2V-t)|=2t;而t=a-1/2V;其中V为已知,则只要a为大于1/2V的最小数即可。
。
。
依照次数学思路,我们可以将该方法进行具体话:
既是将数组降序排列(这一点很重要,可以用数学分析法进行证明),然后将数组的一个元素赋给a,如果a加上该元素后大于b,则将下一个元素赋给b,循环进行判断直至数组结束。
。
。
数学证明过程略
◎代码如下:
#include
usingnamespacestd;
#defineMaxSize50
void
collat(intn,intv)
{
inta=0;
intb=0;
intAlan[MaxSize]={0},Bob[MaxSize]={0},r=0,s=0;
for(inti=n;i>0;i--)
{
if(a>b)
{
b=b+v*i;
Bob[r]=v*i;
r++;
}
else
{
a=a+v*i;
Alan[s]=v*i;
s++;
}
}
cout<<"Alan分配到的礼物为:
"<for(intj=0;j{
cout<}
cout<cout<<"Bob分配到的礼物为:
"<for(intk=0;k{
cout<}
cout<cout<<"Alan分配到的礼物总价值为:
"<cout<<"Bob分配到的礼物总价值为:
"<
}
intmain()
{
intnum,v;
cout<<"请输入礼物的个数:
";
cin>>num;
cout<<"请输入单位礼物的价值:
";
cin>>v;
collat(num,v);
return0;
}
7.键盘输入一个高精度的正整数N,去掉其中任意S个数字后剩下的数字按左右次序将组成一个新的正整数.编程对给定的N和S,寻找一种方案使得剩下的数字组成的新数最小.
◎代码如下:
#include
usingnamespacestd;
#defineMaxSize50
#defineT10
voidOrderArray(intN,intS)
{intarray[MaxSize]={0};
inti=0,j,a=N,max,tag;
while(N>=10)
{array[i]=N%10;
N=N/10;
i++;}
array[i]=N;
for(j=0;j
{for(intp=i;p>=0;p--)
{if(array[p]>array[p-1])
{for(ints=p;s<=i;s++)
array[s]=array[s+1];
i--;break;}
}
}
for(intr=i;r>=0;r--)
cout<intmain()
{
OrderArray(12435863,2);
return0;
}
8.最佳调度问题。
假设有个任务由个并行的机器完成。
完成任务i个需要的时间为。
试设计一个算法找出完成这个任务的最佳调度,使得完成全部任务的时间最早。
◎分析:
可使用贪心算法解决该题目,对于n个任务,k个并行的机器,如果n<=k,则最优调度为每一台机器完成一个任务,完成总时间为n;2.如果n>=k,则先将n个任务进行降序排序,然后完成前k个任务,接着如果完成任务的机器还有时间完成后面的任务,则将任务该由机器完成,直至所有任务完成;
◎代码如下:
#include
usingnamespacestd;
voidBestAlloct(intarray[],intn,intk)
{
inti,j,change=1,sum=0;
inttemp;
for(i=n-1;i>0&&change;i--)
{
change=0;
for(j=0;j
if(array[j]{
change=1;
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
if(n<=k)
{
cout<<"最少时间为:
"<}
else
{
for(intr=0;r{
sum=sum+array[r];
for(intp=1;p{
intsum2=array[r+p];
for(ints=r+k;s{
if(sum2+array[s]<=array[r])
{
sum2=sum2+array[s];
array[s]=0;
}
}
}
}
Cout<<”最少时间为:
”<}
}
intmain()
{
inta[6]={15,14,12,10,6};
BestAlloct(a,6,3);
return0;
}