1. 程式人生 > 其它 >記一次360靶場考核

記一次360靶場考核

例一:求最長上升序列

題目描述
設有由n個不相同的整陣列成的數列,記為:b(1)、b(2)、……、b(n)且b(i)<>b(j) (i<>j),若存在i1<i2<i3< … < ie 且有b(i1)<b(i2)< … <b(ie)則稱為長度為e的不下降序列。程式要求,當原數列出之後,求出最長的上升序列。
例如13,7,9,16,38,24,37,18,44,19,21,22,63,15。例中13,16,18,19,21,22,63就是一個長度為7的不下降序列,同時也有7 ,9,16,18,19,21,22,63長度為8的不下降序列。

輸入格式
只有一行,為若干正整數(最多1000個數)

輸出格式
為兩行,第一行為最上升序列的長度。 第二行為該序列

樣例
樣例輸入
13 7 9 16 38 24 37 18 44 19 21 22 63 15
樣例輸出
max=8
7 9 16 18 19 21 22 63

兩種方法其實也沒什麼本質上的區別
法一

#include<bits/stdc++.h> 
using namespace std;
int a,count1=0,max1=0,maxi,ans[1005],count2=0;
struct str{
	int b;
	int f;
	int before;
}q[1005];
int main (){
	while(cin>>a){
		q[++count1].b=a;
		q[count1].f=1;//F(i)為b[1.....i]中的最長上升子序列長度(以b[i]為結尾)
	}
	for(int i=2;i<=count1;i++){
		for(int j=1;j<i;j++){
			if(q[i].b>q[j].b&&q[i].f<q[j].f+1){
				q[i].f=q[j].f+1;
				q[i].before=j;//before(j)記錄與a[i]相連的上一個下標--記錄路徑 
			}
		}
		if(q[i].f>max1){
			max1=q[i].f;
			maxi=i;
		}
	}
	cout<<"max="<<max1<<endl;
	for(;maxi>=1;maxi=q[maxi].before){
		ans[++count2]=maxi;
	}
	for(int i=count2;i>=1;i--){
		cout<<q[ans[i]].b<<" ";
	}
	return 0;
}

法二

#include<bits/stdc++.h>
using namespace std;
int n,x,max1,l;
int a[1005],before[1005],dp[1005],ans[1005];
void input(){
	while(cin>>x){
		a[++n]=x;
		dp[n]=1;
	}
	//cout<<"@@@"<<n<<endl;
}
void success(){
	for(int i=2;i<=n;i++){
		for(int j=1;j<i;j++){
			if(a[j]<a[i]&&dp[j]>dp[before[i]]){//j不僅要比i大,盲點:::更要找連線最多的 
				before[i]=j;
				dp[i]=dp[j]+1;
			}
			//else dp[i]=dp[i];
		}
	}
}
void output(){
	max1=0;dp[max1]=0;
	for(int i=1;i<=n;i++){
	//	cout<<dp[i]<<endl;
		if(dp[i]>dp[max1]) 
			max1=i;//尋找最大dp值下標
	}
	cout<<"max="<<dp[max1]<<endl;
	for(;max1>=1;max1=before[max1]){
			ans[++l]=max1;//ans 存下標 
	}
	for(int i=l;i>=1;i--){
		cout<<a[ans[i]]<<" ";
	}
}
int main (){
	input();
	success();
	output();
	return 0;
}