BZOJ 3357 [Usaco2004]等差數列:map優化dp

Leohh發表於2017-10-24

題目連結: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 }

 

相關文章