/*
* Problem :: 11052 / 카드 구매하기
*
* Kind :: Dynamic Programming
*
* Insight
* - P[i] = 카드가 i개 들어있는 카드팩의 가격
* dp[i][j] = 카드가 1~i 개 들어있는 카드팩을 적절히 구매해서
* 카드 j개를 갖기 위해 지불해야 하는 금액의 최댓값
* + dp[i][j] = dp[i-1][j]
* if (j >= i) {
* dp[i][j] = max(dp[i][j], dp[i][j-i] + P[i]);
* }
* # dp[1][1] ... dp[1][N] <= i=1
* dp[2][1] ... dp[2][N] <= i=2
* dp[3][1] ... dp[3][N] <= i=3
* ...
* |
* V
* dp[1] ... dp[N] <= i=1
* dp[1] ... dp[N] <= i=2
* dp[3] ... dp[N] <= i=3
* -> 따라서, dp를 2차원 배열이 아닌 1차원 배열로 사용해서
* 메모리 사용량을 줄일 수 있다
*
* Point
* - DP 를 돌 때 i=k 인 경우
* 카드가 k개 들었으므로
* dp[k] 부터 확인해주면 된다
* + for (int i=1; i<=N; i++) {
* for (int j=i; j<=N; j++) {
* <DP>
* codes
* </DP>
* }
* }
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; cin >> N;
int P[N+1];
for (int i=1; i<=N; i++)
cin >> P[i];
// Process
int dp[N+1];
memset(dp, 0, sizeof(dp));
for (int i=1; i<=N; i++) {
for (int j=i; j<=N; j++) {
dp[j] = max(dp[j], dp[j-i]+P[i]);
}
}
// Control : Output
cout << dp[N] << endl;
}
// Helper Functions
/* None */