#include using namespace std; #define rep(i, n) for (int i = 0; i < (int)(n); i++) #define length size() #define int long long #define ll long long constexpr ll inf = 1001001001001001001ll; constexpr ll mod = 1000000007; constexpr double pi = 3.141592653589793; //小数出力 //cout << std::setprecision(12); //imos void to_ruiseki(vector &vec){ for(int i=1;i> &vec){ rep(i,vec.size()){ rep(j,vec[0].size()){ int s = 0; if(i!=0) s += vec[i-1][j]; if(j!=0) s += vec[i][j-1]; if(i!=0 && j!=0) s -= vec[i-1][j-1]; s += vec[i][j]; vec[i][j] = s; } } } //modpow(a,n,mod) int modpow(int a, int n, int mod) { long long res = 1; while (n > 0) { if (n & 1) res = res * a % mod; a = a * a % mod; n >>= 1; } return res; } //素因数分解 vector> p_fact(int N) { vector> res; for (int a = 2; a * a <= N; ++a) { if (N % a != 0) continue; int ex = 0; // 指数 // 割れる限り割り続ける while (N % a == 0) { ++ex; N /= a; } // その結果を push res.push_back({a, ex}); } // 最後に残った数について if (N != 1) res.push_back({N, 1}); return res; } //ctoi int ctoi(const char c){ switch(c){ case '0': return 0; case '1': return 1; case '2': return 2; case '3': return 3; case '4': return 4; case '5': return 5; case '6': return 6; case '7': return 7; case '8': return 8; case '9': return 9; default : throw runtime_error("hoge"); } } //max template< typename T1, typename T2 > inline bool chmax(T1 &a, T2 b) { return a < b && (a = b, true); } //min template< typename T1, typename T2 > inline bool chmin(T1 &a, T2 b) { return a > b && (a = b, true); } //print void print() { cout << '\n'; } template void print(const T &t) { cout << t << '\n'; } template void print(const Head &head, const Tail &... tail) { cout << head << ' '; print(tail...); } //join template string join(vector &vec ,const string &sp){ int si = vec.length; if(si==0){ return ""; }else{ stringstream ss; rep(i,si-1){ ss << vec[i] << sp; } ss << vec[si - 1]; return ss.str(); } } //木の直径 int tree_diameter(vector> &vec){ //0-indexed queue> que; vector is_searched(vec.size(),false); que.push(make_pair(0,0)); int max_d = 0; int max_e = 0; while(!que.empty()){ int e = que.front().first; int distance = que.front().second; is_searched[e] = true; if(max_d> &vec,int st){ queue> que; vector is_searched(vec.size(),false); is_searched[st] = true; que.push(make_pair(st,0)); int max_d = 0; int max_e = 0; while(!que.empty()){ int e = que.front().first; int distance = que.front().second; if(max_d par, rank, siz; // 構造体の初期化 UnionFind(int n) : par(n,-1), rank(n,0), siz(n,1) { } // 根を求める int root(int x) { if (par[x]==-1) return x; // x が根の場合は x を返す else return par[x] = root(par[x]); // 経路圧縮 } // x と y が同じグループに属するか (= 根が一致するか) bool issame(int x, int y) { return root(x)==root(y); } // x を含むグループと y を含むグループを併合する bool unite(int x, int y) { int rx = root(x), ry = root(y); // x 側と y 側の根を取得する if (rx==ry) return false; // すでに同じグループのときは何もしない // union by rank if (rank[rx]0){ if(!is_searched_now[x-1][y] && vec[x-1][y] != '#'){ saiki(x-1,y,s+1); } if(vec[x-1][y] == 'g' && s >=2) chmax(max_ans,s+1); } if(x=2) chmax(max_ans,s+1); } if(y>0){ if(!is_searched_now[x][y-1] && vec[x][y-1] != '#'){ saiki(x,y-1,s+1); } if(vec[x][y-1] == 'g' && s >=2) chmax(max_ans,s+1); } if(y=2) chmax(max_ans,s+1); } //is_searched[x][y] = true; is_searched_now[x][y] = false; } signed main(void){ int n,a,b,c; cin >> n >> a >> b >> c; vector dp(n+1,0); dp[0] = 0; for(int i=1;i<=n;i++){ dp[i] = max(dp[i-1],max((i>=3)?dp[i-3]+a:0,max((i>=5)?dp[i-5]+b:0,(i>=10)?dp[i-10]+c:0))); } //print(join(dp," ")); print(dp[n]); }