1. 程式人生 > >2016級算法期末模擬練習賽-D.AlvinZH的序列問題

2016級算法期末模擬練習賽-D.AlvinZH的序列問題

logs fin create 問題 name res 要求 esp while

1111 AlvinZH的序列問題

思路

中等題,動態規劃。

簡化題意,。

坑點一:二維int數組MLE,明顯會超過內存限制,由於\(n\)最大為1e4,那麽我們的dp數組最大也是1e4,考慮使用short int。

坑點而:被題目開始的子序列描述誤導,題目沒有要求等差數列中數字順序和輸入順序一致,所以可以先將數組排序。

dp[i][j]:以A[i]、A[j]開頭的等差數列(可保證i<j)。初始化值為2。

狀態轉移:固定j,i與k分別向兩邊擴展,當2*A[j]=A[i]+A[k]時,說明A[i]、A[j]、A[k]可以組成等差數列。則有:dp[i][j]=dp[j][k]+1。

分析

這個DP也很有意思哦,固定一維,向兩邊擴展,真是妙啊!

時間復雜度:接近\(O(n^2)\)

參考代碼

//
// Created by AlvinZH on 2017/11/27.
// Copyright (c) AlvinZH. All rights reserved.
//

#include <cstdio>
#include <iostream>
#include <algorithm>
#define MaxSize 10005
using namespace std;

int n, ans;
int A[MaxSize];
short int dp[MaxSize][MaxSize];

int main()
{
    while
(~scanf("%d", &n)) { for (int i = 0; i < n; ++i) scanf("%d", &A[i]); sort(A, A+n); for (int i = 0; i < n; ++i) for (int j = i+1; j < n; ++j) dp[i][j] = 2; ans = 2; for (int j = n-2
; j > 0; --j) { int i = j-1, k = j+1; while(i>=0 && k<n) { if(A[i]+A[k] < 2*A[j]) k++; else if(A[i]+A[k] > 2*A[j]) i--; else { dp[i][j] = dp[j][k] + 1; if(dp[i][j] > ans) ans = dp[i][j]; i--, k++; } } } printf("%d\n", ans); } }

2016級算法期末模擬練習賽-D.AlvinZH的序列問題