【dp&&题解&&作业】51nod1055最长等差数列

41 篇文章 0 订阅
8 篇文章 0 订阅

题目传送门

题目描述:

N个不同的正整数,找出由这些数组成的最长的等差数列。
例如:1 3 5 6 8 9 10 12 13 14
等差子数列包括(仅包括两项的不列举)
1 3 5
1 5 9 13
3 6 9 12
3 8 13
5 9 13
6 8 10 12 14
其中6 8 10 12 14最长,长度为5。


输入
第1行:N,N为正整数的数量(3 <= N <= 10000)。
第2 - N+1行:N个正整数。(2<= A[i] <= 10^9)


输出
最长等差数列的长度。


输入样例
10
1
3
5
6
8
9
10
12
13
14


输出样例
5


分析:这是一道dp的题目。设dp[i][j]表示第一个数为a[i],第二个数为a[j],所构成的最长的等差数列长度。枚举k,如果a[k]可以作为等差数列的第三项,那么就一定满足a[j]*2=a[i]+a[k]。又发现这个东西具有单调性,所以我们只要倒的转移,用两个指针扫k的前面和后面,就行了

那么具体代码如下:

#include<bits/stdc++.h>
using namespace std;
#define GC getchar()
short int dp[10010][10010];//表示第一项为a[i],第二项为a[j]的最长 
int a[100001];
short int maxx=0;
int n;
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;i++) scanf("%d",&a[i]);
//    cout<<n<<' '<<a[1]<<' '<<a[2]<<endl;
//    if (n==100) {cout<<30;return 0;}
    sort(a+1,a+n+1);
    for (int i=1;i<=n;i++)
      for (int j=i+1;j<=n;j++)
        dp[i][j]=2;
    for (int j=n;j>=2;j--){
	    int i=j-1,k=j+1;
	    while (i>0&&k<=n){
		    if (a[i]+a[k]>a[j]*2) i--;
		    if (a[i]+a[k]<a[j]*2) k++;
		    if (a[i]+a[k]==a[j]*2) dp[i][j]=dp[j][k]+1,maxx=max(maxx,dp[i][j]),i--,k++;
		}
	}
//	short int maxx=0;
	for (int i=1;i<=n;i++)
	  for (int j=i+1;j<=n;j++)
	    maxx=max(maxx,dp[i][j]);
	cout<<maxx;
	return 0;
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值