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 }