BZOJ 3357 [Usaco2004]等差数列:map优化dp

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3357

题意:

  给你n个数a[i],让你找出一个最长的是等差数列的子序列。

 

题解:

  表示状态:

    dp[i][a[j]] = max len

    表示当前选了a[i],上一个数是a[j]时,最长的等差数列长度。

 

  找出答案:

    max dp[i][a[j]]

 

  如何转移:

    map<int,int> dp[MAX_N];

    dp[i][a[j]] = max dp[a[j]][2*a[j] - a[i]]

 

  边界条件:

 

    dp[i][j] = 2 (j < i)

 

AC Code:

 1 // state expression:
 2 // dp[i][a[j]] = max len
 3 // i: considering ith num
 4 // j: last num
 5 //
 6 // find the answer:
 7 // max dp[i][a[j]]
 8 //
 9 // transferring:
10 // dp[i][a[j]] = max dp[a[j]][2*a[j] - a[i]]
11 //
12 // boundary:
13 // dp[i][j] = 2
14 // dp[i][i] = 1
15 #include <iostream>
16 #include <stdio.h>
17 #include <string.h>
18 #include <map>
19 #define MAX_N 2005
20 
21 using namespace std;
22 
23 int n;
24 int ans=1;
25 int a[MAX_N];
26 map<int,int> dp[MAX_N];
27 
28 void read()
29 {
30     cin>>n;
31     for(int i=0;i<n;i++)
32     {
33         cin>>a[i];
34     }
35 }
36 
37 void solve()
38 {
39     for(int i=0;i<n;i++)
40     {
41         for(int j=0;j<i;j++)
42         {
43             dp[i][a[j]]=2;
44             dp[i][a[j]]=max(dp[i][a[j]],dp[j][2*a[j]-a[i]]+1);
45             ans=max(ans,dp[i][a[j]]);
46         }
47     }
48 }
49 
50 void print()
51 {
52     cout<<ans<<endl;
53 }
54 
55 int main()
56 {
57     read();
58     solve();
59     print();
60 }

 

posted @ 2017-10-24 16:46  Leohh  阅读(294)  评论(0编辑  收藏  举报