Problem J: Arithmetic Sequence

Problem J: Arithmetic Sequence

Time Limit: 1 Sec   Memory Limit: 128 MB
Submit: 0   Solved: 0

Description

    Giving a number sequence A with length n, you should choosing m numbers from A(ignore the order) which can form an arithmetic sequence and make m as large as possible.

Input

   There are multiple test cases. In each test case, the first line contains a positive integer n. The second line contains n integers separated by spaces, indicating the number sequence A. All the integers are positive and not more than 2000. The input will end by EOF.

Output

   For each test case, output the maximum  as the answer in one line.

Sample Input

5
1 3 5 7 10
8
4 2 7 11 3 1 9 5

Sample Output

4
6

HINT

   In the first test case, you should choose 1,3,5,7 to form the arithmetic sequence and its length is 4.


   In the second test case, you should choose 1,3,5,7,9,11 and the length is 6.

解题思路:给你一个大小为n的数组,要你从中选出尽可能多的m个元素组成一个等差数列(不考虑元素在数组里的位置),问m最大是多少

因为与位置无关,所以不管三七二十一,先把原数组排序

又因为题目规模不大,所以我们不妨考虑动态规划

假设dp[i][j]表示以第i个元素结尾公差为j的等差数列项数

那么我们可以得到转移方程


那么最终的结果为最大的dp[s[i]][j]值

/*Sherlock and Watson and Adler*/
#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<map>
#include<set>
#include<cmath>
#include<complex>
#include<string>
#include<algorithm>
#include<iostream>
#define exp 1e-10
using namespace std;
const int N = 2005;
const int M = 40;
const int inf = 100000000;
const int mod = 2009;
int dp[N][N],s[N];
int main()
{
    int n,i,j,Max,Min,ans;
    while(~scanf("%d",&n))
    {
        ans=1;Max=0;Min=inf;
        memset(dp,0,sizeof(dp));
        for(i=0;i<n;i++)
        {
            scanf("%d",&s[i]);
            Max=max(Max,s[i]);
            Min=min(Min,s[i]);
        }
        sort(s,s+n);//printf("%d %d\n",Max,Min);
        for(i=0;i<=Max-Min;i++)
            dp[s[0]][i]=1;
        for(i=1;i<n;i++)
            for(j=0;j<=Max-Min;j++)
            {
                if(j<=s[i])
                    dp[s[i]][j]=dp[s[i]-j][j]+1;
                else
                    dp[s[i]][j]=1;
                ans=max(ans,dp[s[i]][j]);
            }
        printf("%d\n",ans);
    }
    return 0;
}
 
/**************************************************************
    Problem: 21
    Language: C++
    Result: Accepted
    Time:549 ms
    Memory:17216 kb
****************************************************************/

菜鸟成长记

你可能感兴趣的:(dp,ACM)