1. 程式人生 > >作業題(最長不下降或上升)

作業題(最長不下降或上升)

作業題

時間限制:3000 ms  |  記憶體限制:65535 KB 難度:3
描述

小白同學這學期有一門課程叫做《數值計算方法》,這是一門有效使用數字計算機求數學問題近似解的方法與過程,以及由相關理論構成的學科……

今天他們的Teacher S,給他們出了一道作業題。Teacher S給了他們很多的點,讓他們利用拉格朗日插值公式,計算出某嚴格單調函式的曲線。現在小白抄下了這些點,但是問題出現了,由於我們的小白同學上課時走了一下神,他多抄下來很多點,也就是說這些點整體連線不一定還是嚴格遞增或遞減的了。這可怎麼處理呢。為此我們的小白同學制定了以下的取點規則:

1、取出儘可能多的滿足構成嚴格單調曲線的點,作為曲線上的點。

2、通過拉格朗日插值公式,計算出曲線的方程

但是,他又遇到了一個問題,他發現他寫下了上百個點。[- -!佩服吧],這就很難處理了(O_O).。由於拉格朗日插值公式的計算量與處理的點數有關,因此他請大家來幫忙,幫他統計一下,曲線上最多有多少點,以此來估計計算量。

已知:沒有任何兩個點的橫座標是相同的。

輸入
本題包含多組資料:
首先,是一個整數T,代表資料的組數。
然後,下面是T組測試資料。對於每組資料包含兩行:
第一行:一個數字N(1<=N<=999),代表輸入的點的個數。
第二行:包含N個數對X(1<=x<=10000),Y(1<=Y<=10000),代表所取的點的橫縱座標。
輸出
每組輸出各佔一行,輸出公一個整數,表示曲線上最多的點數
樣例輸入
2
2
1 2 3 4
3
2 2 1 3 3 4
樣例輸出
2
2
來源

將橫座標升序排列後,求出縱座標的最長遞增序列長度與最長遞減序列長度

#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;

struct point
{
    int x;
    int y;
};

bool cmp(point a,point b)
{
    return a.x<b.x;
}
int DP[1005],DP1[1005];
int main()
{
    point a[1000];
    int T,N,i,j;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d",&N);
        for(i=0;i<N;i++)
        {
            scanf("%d %d",&a[i].x,&a[i].y);
            DP[i]=1;DP1[i]=1;
        }
        sort(a,a+N,cmp);
		int max1=0,max2=0;
		 for(i=0;i<N;++i)  
        {  
            DP[i]=1; 
			DP1[i]=1;
            for(j=0;j<=i-1;++j)  
            {  
                if(a[j].y<a[i].y&&DP[j]+1>DP[i])  
                    DP[i]=DP[j]+1;  
				if(a[j].y>a[i].y&&DP1[j]+1>DP1[i])  
                    DP1[i]=DP1[j]+1;  
            }  
            if(DP[i]>max1)  
                max1=DP[i]; 
			if(DP1[i]>max2)  
                max2=DP1[i];
        }  
       if(max1>max2)
			printf("%d\n",max1);
	   else
		    printf("%d\n",max2);
    }
}

照樣水

#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int dp[10000];
struct point
{
    int x;
    int y;
};

bool cmp(point a,point b)
{
    return a.x<b.x;
}

int main()
{
	point a[1000];
	int t;
	cin>>t;
	while(t--)
	{
		int n,i,j;
		
		cin>>n;
		for(i=0;i<n;++i)
		{
			cin>>a[i].x;
			cin>>a[i].y;
		}
		sort(a,a+n,cmp);
		int max1=-1,max2=-1;
		
		  for(i=0;i<n;++i)  
        {  
            dp[i]=1;  
            for(j=0;j<=i-1;++j)  
            {  
                if(a[j].y<a[i].y&&dp[j]+1>dp[i])  
                    dp[i]=dp[j]+1;  
            }  
            if(dp[i]>max1)  
                max1=dp[i];  
        }  
		
		   for(i=0;i<n;++i)  
        {  
            dp[i]=1;  
            for(j=0;j<=i-1;++j)  
            {  
                if(a[j].y>a[i].y&&dp[j]+1>dp[i])  
                    dp[i]=dp[j]+1;  
            }  
            if(dp[i]>max2)  
                max2=dp[i];  
        }
		   if(max1>max2)
				cout<<max1<<endl; 
		   else
			   cout<<max2<<endl; 
	}
}