Problem:
貨物列車 (Freight Train)
問題文
IOI 鉄道は
1
本の鉄道路線を運営している．IOI 鉄道線には一直線上に並んだ
N
個の駅があり，順に
1
から
N
までの番号が付けられている．各
i
(
1 ≦ i ≦ N - 1
) に対して，駅
i
と駅
i + 1
の間は線路で結ばれており，その長さは
1
である．
IOI 鉄道は貨物を取り扱っている．駅
2, 3, …, N
には貨物が
1
つずつ置かれており，駅
i
(
2 ≦ i ≦ N
) に置かれている貨物の価値は
A
i
である．
IOI 鉄道は貨物列車を
1
編成所有している．この列車は最初駅
1
におり，IOI 鉄道線上を双方向に走行できる．それぞれの駅では，その駅に置いてある貨物を列車に積むことや，列車に積まれている貨物を下ろし，その駅に置いておくことができる．
この貨物列車を用いて 駅
2, 3, …, N
に置かれている貨物を駅
1
に輸送したい．ただし，この列車には貨物を
W
個以下しか載せることができない．すなわち，どの時点においても列車に貨物が
W + 1
個以上載っていることは許されない．また，この列車は燃料の都合上，最大でも総距離
D
しか走行することができない．そのため，すべての貨物を駅
1
に輸送することはできないかもしれない．
IOI 鉄道の社長である JOI くんは，この条件のもと適切に貨物列車を走行させることで，最終的に駅
1
に置かれている貨物の価値の合計をなるべく大きくしたい．
貨物列車の情報と各駅に置かれている貨物の情報が与えられたとき，最終的に駅
1
に置かれている貨物の価値の合計として達成可能な最大値を求めるプログラムを作成せよ．
制約
2 ≦ N ≦ 450
．
1 ≦ W ≦ N - 1
．
2 ≦ D ≦ N
2
- N
．
1 ≦ A
i
≦ 1000000
(
2 ≦ i ≦ N
)．
入力される値はすべて整数である．
入力
入力は以下の形式で与えられる．
N
W
D
A
2
A
3
…
A
N
出力
最終的に駅
1
に置かれている貨物の価値の合計として達成可能な最大値を
1
行で出力せよ．
入出力例
入力例 1
4 1 10
1 1 1
出力例 1
2
例えば，以下のように貨物列車を走行させると最終的に駅
1
に置かれている貨物の価値の合計を
2
にすることができる．
最初，貨物列車は駅
1
にいる．
貨物列車を駅
2
に走行させる．
駅
2
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている価値
1
の貨物を駅
1
に置く．
貨物列車を駅
4
に走行させる．
駅
4
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている価値
1
の貨物を駅
1
に置く．
列車の走行した総距離は
8
であり，列車が総距離
10
以下しか走行できないという条件を満たしている．
このとき，最終的に駅
1
に置かれている貨物の価値の合計は
2
である．最終的に駅
1
に置かれている貨物の価値の合計を
3
以上にすることはできないため，
2
を出力する．
入力例 2
7 3 16
1 1 1 1 1 1
出力例 2
5
例えば，以下のように貨物列車を走行させると最終的に駅
1
に置かれている貨物の価値の合計を
5
にすることができる．
最初，貨物列車は駅
1
にいる．
貨物列車を駅
5
に走行させる．
駅
5
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
6
に走行させる．
駅
6
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている
2
つの価値
1
の貨物をすべて駅
1
に置く．
貨物列車を駅
2
に走行させる．
駅
2
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
3
に走行させる．
駅
3
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
4
に走行させる．
駅
4
に置かれている価値
1
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている
3
つの価値
1
の貨物をすべて駅
1
に置く．
列車の走行した総距離は
16
であり，列車が総距離
16
以下しか走行できないという条件を満たしている．
このとき，最終的に駅
1
に置かれている貨物の価値の合計は
5
である．最終的に駅
1
に置かれている貨物の価値の合計を
6
以上にすることはできないため，
5
を出力する．
入力例 3
5 2 12
40 30 20 10
出力例 3
100
例えば，以下のように貨物列車を走行させると最終的に駅
1
に置かれている貨物の価値の合計を
100
にすることができる．
最初，貨物列車は駅
1
にいる．
貨物列車を駅
5
に走行させる．
駅
5
に置かれている価値
10
の貨物を貨物列車に積む．
貨物列車を駅
4
に走行される．
駅
4
に置かれている価値
20
の貨物を貨物列車に積む．
貨物列車を駅
2
に走行させる．
貨物列車に積まれている価値
10
の貨物と価値
20
の貨物を駅
2
に置く．
駅
2
に置かれている価値
40
の貨物を貨物列車に積む．
貨物列車を駅
3
に走行させる．
駅
3
に置かれている価値
30
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている価値
30
の貨物と価値
40
の貨物を駅
1
に置く．
貨物列車を駅
2
に走行させる．
駅
2
に置かれている価値
10
の貨物と価値
20
の貨物を貨物列車に積む．
貨物列車を駅
1
に走行させる．
貨物列車に積まれている価値
10
の貨物と価値
20
の貨物を駅
1
に置く．
列車の走行した総距離は
12
であり，列車が総距離
12
以下しか走行できないという条件を満たしている．
このとき，最終的に駅
1
に置かれている貨物の価値の合計は
100
である．最終的に駅
1
に置かれている貨物の価値の合計を
101
以上にすることはできないため，
100
を出力する．
入力例 4
5 1 11
2 7 1 8
出力例 4
10
入力例 5
9 3 14
54640 754112 604290 105866 591907 801383 502975 379373
出力例 5
2214425
情報オリンピック日本委員会
作 『第 22 回日本情報オリンピック JOI 2022/2023 二次予選競技課題』

Submitted solutions:

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define RFOR(i,l,r) for(ll i=r-1;i>=l;i--)
#define RREP(i,n) RFOR(i,0,n)
int main(){
    ll n,w,d;cin>>n>>w>>d;
    d/=2;
    d=min(d,(n/w+1)*(n/w+2)/2*w);
    vector<int>a(n);
    FOR(i,1,n)cin>>a[i];
    vector<vector<int>>dp(d+1,vector<int>(w,-1e9));
    REP(k,w)dp[0][k]=0;
    int ans=0;
    FOR(i,1,n){
        RREP(j,d+1-i)RREP(k,w){
            if(k<w-1)dp[j][k+1]=max(dp[j][k+1],dp[j][k]+a[i]);
            else if(j+i<=d){
                dp[j+i][0]=max(dp[j+i][0],dp[j][k]+a[i]);
                ans=max(ans,dp[j+i][0]);
            }
        }
    }
    cout<<ans<<endl;
    return 0;
}
accuracy: 1
time_ms: 160
memory_kb: 8624
final_rank: 2

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll=long long;

int main(){
    ll N,W,D;
    cin>>N>>W>>D;
    D/=2;
    vector<ll> A(N-1);
    for(ll i=0;i<N-1;i++)cin>>A[i];

    ll LL=0;
    for(int i=N-1;i>0;i-=W){
        LL+=i;
    }
    if(LL<=D){
        ll an=0;
        for(int i=0;i<N-1;i++){
            an+=A[i];
        }
        cout<<an<<endl;
        return 0;
    }
    vector<vector<ll>> DP(D+1,vector<ll>(W,-1e18));
    DP[0][0]=0;
    ll an=0;

    for(int n=0;n<N-1;n++){
        vector<vector<ll>> NDP=DP;
        for(int d=0;d<=D;d++){
            for(int w=0;w<W;w++){
                if(w+1<W){
                    NDP[d][w+1]=max(NDP[d][w+1],DP[d][w]+A[n]);
                }
                if(d+(n+1)<=D){
                    NDP[d+(n+1)][0]=max(NDP[d+(n+1)][0],DP[d][w]+A[n]);
                    an=max(NDP[d+(n+1)][0],an);
                }
            }
        }
        swap(DP,NDP);
    }
    cout<<an<<endl;
}
accuracy: 1
time_ms: 1350
memory_kb: 14016
final_rank: 6

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>

using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000LL // オーバーフローに注意
#define MOD 998244353
// #define MOD 1000000007
#define EPS 0.000000001

#define SIZE 450

int A[SIZE];
vector<vector<vector<int>>> dp;

int main() {
    int N, W, D;
    cin >> N >> W >> D;

    for (int i = 2; i <= N; ++i) {
        cin >> A[i];
    }

    // 必要な燃料の最大量を求める
    int work = 0;
    int rest = (N - 1);
    while (true) {
        work += 2 * rest;
        rest -= W;
        if (rest <= 0) break;
    }

    D = min(D, work);

    dp.resize(2, vector<vector<int>>(W, vector<int>(D + 1, -1)));

    int now = 0, next = 1;
    int ans = 0;

    dp[now][W - 1][D] = 0;

    for (int i = N; i >= 2; --i) {
        // 選ばない
        for (int k = 0; k < W; ++k) {
            for (int p = 0; p <= D; ++p) {
                dp[next][k][p] = dp[now][k][p];
            }
        }

        // 選ぶ
        for (int k = 0; k < W; ++k) {
            for (int p = 0; p <= D; ++p) {
                if (dp[now][k][p] == -1) continue;

                int tmp = dp[now][k][p] + A[i];

                if (k == W - 1) { // 次が右端
                    if (p >= 2 * (i - 1)) {
                        chmax(dp[next][0][p - 2 * (i - 1)], tmp);
                        chmax(ans, tmp);
                    }
                } else { // 右端でないので燃料を消費しない
                    chmax(dp[next][k + 1][p], tmp);
                    chmax(ans, tmp);
                }
            }
        }
        swap(now, next);
    }

    cout << ans << endl;

    return 0;
}
accuracy: 1
time_ms: 210
memory_kb: 7840
final_rank: 5

code_snippet: #include <iostream>
#include <string.h>
#include <map>
using namespace std;

struct E{
	int time;
	int value;
};

const int M=453;
E dp[M][M];
int ds[M];
int main() {
	// your code goes here
	memset(ds,0,sizeof(ds));
	int n,w,d;
	cin>>n>>w>>d;
	
	
	for(int i=2;i<=n;i++){
		cin>>ds[i];
	}
	for(int i=0;i<=n;i++){
		for(int j=0;j<=n;j++){
			E e;
			e.time=0;
			e.value=0;
			dp[i][j]=e;
		}
	}
	for(int i=3;i<=n;i++){
		E e;
		e.time=2;
		e.value=ds[i];
		dp[1][i-1]=e;
	}
	int ans=ds[2];
	for(int i=0;i<=n;i++){
		for(int j=n;j>=1;j--){
			int c0=(j-1)/w*2+2;
			int c1=(j)/w*2+2;
			for(int k=2;k<=n;k++){
				E e=dp[j][k];
				E e2=dp[j][k];
				if(e.time==0)continue;
				if(e.time+c0<=d){
					e2.time=e.time+c0;
					dp[j][k-1]=e2;
				}
				if(j+1<=n && e.time+c1<=d){
					e2.time=e.time+c1;
					e2.value=e.value+ds[k];
					dp[j+1][k-1]=e2;
				}
			}

		}
		for(int j=1;j<=n;j++){
			E e=dp[j][1];
			if(0<e.time && ans<e.value){
				ans=e.value;
			}
		}
	}
	cout<<ans<<endl;
	return 0;
}
accuracy: 0.41830065359477125
time_ms: 70
memory_kb: 4700
final_rank: 9

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 998244353
//#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 450

int A[SIZE];
int ***dp;


int main(){

	int N,W,D;
	scanf("%d %d %d",&N,&W,&D);

	for(int i = 2; i <= N; i++){

		scanf("%d",&A[i]);
	}

	//必要な燃料の最大量を求める
	int work = 0;
	int rest = (N-1);
	while(true){

		work += 2*rest;
		rest -= W;
		if(rest <= 0)break;
	}

	D = min(D,work);

	dp = new int**[2];
	for(int i = 0; i < 2; i++){
		dp[i] = new int*[W];
		for(int k = 0; k < W; k++){

			dp[i][k] = new int[D+1];
			for(int p = 0; p <= D; p++){

				dp[i][k][p] = -1;
			}
		}
	}

	int now = 0,next = 1;
	int ans = 0;

	dp[now][W-1][D] = 0;

	for(int i = N; i >= 2; i--){

		//選ばない
		for(int k = 0; k < W; k++){
			for(int p = 0; p <= D; p++){

				dp[next][k][p] = dp[now][k][p];
			}
		}

		//選ぶ
		for(int k = 0; k < W; k++){
			for(int p = 0; p <= D; p++){
				if(dp[now][k][p] == -1)continue;

				int tmp = dp[now][k][p]+A[i];

				if(k == W-1){ //次が右端

					if(p >= 2*(i-1)){

						chmax(dp[next][0][p-2*(i-1)],tmp);
						chmax(ans,tmp);
					}

				}else{ //右端でないので燃料を消費しない

					chmax(dp[next][k+1][p],tmp);
					chmax(ans,tmp);
				}
			}
		}
		swap(now,next);
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 6376
final_rank: 4

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;
#define chmin(x,y) x = min(x,y)
#define chmax(x,y) x = max(x,y)
#define BIG_NUM 2000000000
#define HUGE_NUM 4000000000000000000 //オーバーフローに注意
#define MOD 998244353
//#define MOD 1000000007
#define EPS 0.000000001




#define SIZE 450

int A[SIZE];
int ***dp;


int main(){

	int N,W,D;
	scanf("%d %d %d",&N,&W,&D);

	for(int i = 2; i <= N; i++){

		scanf("%d",&A[i]);
	}

	int work = 0;
	int rest = (N-1);
	while(true){

		work += 2*rest;
		rest -= W;
		if(rest <= 0)break;
	}

	D = min(D,work);

	//printf("D:%d\n",D);

	dp = new int**[2];
	for(int i = 0; i < 2; i++){
		dp[i] = new int*[W];
		for(int k = 0; k < W; k++){

			dp[i][k] = new int[D+1];
			for(int p = 0; p <= D; p++){

				dp[i][k][p] = -1;
			}
		}
	}

	int now = 0,next = 1;
	int ans = 0;

	dp[now][W-1][D] = 0;

	for(int i = N; i >= 2; i--){

		//選ばない
		for(int k = 0; k < W; k++){
			for(int p = 0; p <= D; p++){

				dp[next][k][p] = dp[now][k][p];
			}
		}

		//printf("\ni:%d\n",i);

		//選ぶ
		for(int k = 0; k < W; k++){
			for(int p = 0; p <= D; p++){
				if(dp[now][k][p] == -1)continue;

				int tmp = dp[now][k][p]+A[i];

				if(k == W-1){ //次が右端

					if(p >= 2*(i-1)){

						chmax(dp[next][0][p-2*(i-1)],tmp);
						//printf("燃料;%d で選んで、tmp;%d\n",p,tmp);
						chmax(ans,tmp);
					}

				}else{ //右端でないので燃料を消費しない

					chmax(dp[next][k+1][p],tmp);
					chmax(ans,tmp);
				}
			}
		}
		swap(now,next);
	}

	printf("%d\n",ans);

	return 0;
}
accuracy: 1
time_ms: 200
memory_kb: 6352
final_rank: 3

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,n) for(int i=1;i<=(n);++i)
#define all(x) begin(x),end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a, b) (((a) + (b) - 1) / (b))
using pii = pair<int,int>;
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int_fast64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod1 = 1e9+7;
constexpr int mod2 = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template<class T, class U> istream& operator>>(istream& is, pair<T, U>& p){ is >> p.first >> p.second; return (is); }
template<class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p){ os << p.first << ' ' << p.second; return (os); }
template<class T> istream& operator>>(istream& is, vector<T>& v){ for (auto &&e : v) is >> e; return (is); }
template<class T> ostream& operator<<(ostream& os, vector<T>& v){ for (auto &&e : v) os << e << ' '; return (os); }

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T, vector<T>, greater<T> >;
template <class A, class B> using umap = unordered_map<A, B>;
template <class T> using uset = unordered_set<T>;

template <class T> using Max_Heap = __gnu_pbds::priority_queue<T, less<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Min_Heap = __gnu_pbds::priority_queue<T, greater<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class K, class V> using Umap = __gnu_pbds::gp_hash_table<K, V>;
template <class T> using Rope = __gnu_cxx::rope<T>;
using Trie = __gnu_pbds::trie<string, __gnu_pbds::null_type, __gnu_pbds::trie_string_access_traits<>, __gnu_pbds::pat_trie_tag, __gnu_pbds::trie_prefix_search_node_update>;

template <class T> void bye(T x){ cout << x << '\n'; exit(0); }
inline int square(int a){ return (a * a); }

constexpr int dx[] = {1,0,-1,0,1,1,-1,-1};
constexpr int dy[] = {0,-1,0,1,1,-1,-1,1};

signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout.setf(ios_base::fixed);
    cout.precision(12);

    int n, w, d;
    cin >> n >> w >> d;

    assert(2 <= n && n <= 450);
    assert(1 <= w && w <= n - 1);
    assert(2 <= d && d <= n * n - n);

    d /= 2;

    vector<int> a(n);

    for (int i = 1; i < n; ++i) {
        cin >> a[i];
        assert(1 <= a[i] && a[i] <= 1000000);
    }

    int maxd = 0, cnt = 0;
    for (int i = n; i >= 1; --i) {
        if (cnt == 0) {
            maxd += i;
        }
        cnt = (cnt + 1) % w;
    }

    chmin(d, maxd);

    vector dp(n + 1, vector(w, vector(d + 1, -INF)));

    dp[n][0][0] = 0;

    int res = 0;
    for (int i = n - 1; i >= 1; --i) {
        for (int j = 0; j < w; ++j) {
            for (int k = 0; k <= d; ++k) {
                if (j == 0) {
                    if (k + i <= d) {
                        chmax(dp[i][(j + 1) % w][k + i], dp[i + 1][j][k] + a[i]);
                    }
                } else{
                    chmax(dp[i][(j + 1) % w][k], dp[i + 1][j][k] + a[i]);
                }
                chmax(dp[i][j][k], dp[i + 1][j][k]);
            }
        }
    }

    for (int j = 0; j < w; ++j) {
        for (int k = 0; k <= d; ++k) {
            chmax(res, dp[1][j][k]);
        }
    }

    cout << res << '\n';

    return (0);
}
accuracy: 1
time_ms: 330
memory_kb: 369516
final_rank: 7

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,n) for(int i=1;i<=(n);++i)
#define all(x) begin(x),end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a, b) (((a) + (b) - 1) / (b))
using pii = pair<int,int>;
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int_fast64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod1 = 1e9+7;
constexpr int mod2 = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template<class T, class U> istream& operator>>(istream& is, pair<T, U>& p){ is >> p.first >> p.second; return (is); }
template<class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p){ os << p.first << ' ' << p.second; return (os); }
template<class T> istream& operator>>(istream& is, vector<T>& v){ for (auto &&e : v) is >> e; return (is); }
template<class T> ostream& operator<<(ostream& os, vector<T>& v){ for (auto &&e : v) os << e << ' '; return (os); }

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T, vector<T>, greater<T> >;
template <class A, class B> using umap = unordered_map<A, B>;
template <class T> using uset = unordered_set<T>;

template <class T> using Max_Heap = __gnu_pbds::priority_queue<T, less<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Min_Heap = __gnu_pbds::priority_queue<T, greater<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class K, class V> using Umap = __gnu_pbds::gp_hash_table<K, V>;
template <class T> using Rope = __gnu_cxx::rope<T>;
using Trie = __gnu_pbds::trie<string, __gnu_pbds::null_type, __gnu_pbds::trie_string_access_traits<>, __gnu_pbds::pat_trie_tag, __gnu_pbds::trie_prefix_search_node_update>;

template <class T> void bye(T x){ cout << x << '\n'; exit(0); }
inline int square(int a){ return (a * a); }

constexpr int dx[] = {1,0,-1,0,1,1,-1,-1};
constexpr int dy[] = {0,-1,0,1,1,-1,-1,1};

signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout.setf(ios_base::fixed);
    cout.precision(12);

    int n, w, d;
    cin >> n >> w >> d;

    d /= 2;

    vector<int> a(n);

    for (int i = 1; i < n; ++i) {
        cin >> a[i];
    }

    int maxd = 0, cnt = 0;
    for (int i = n; i >= 1; --i) {
        if (cnt == 0) {
            maxd += i;
        }
        cnt = (cnt + 1) % w;
    }

    chmin(d, maxd);

    vector dp(n + 1, vector(w, vector(d + 1, -INF)));

    dp[n][0][0] = 0;

    int res = 0;
    for (int i = n - 1; i >= 1; --i) {
        for (int j = 0; j < w; ++j) {
            for (int k = 0; k <= d; ++k) {
                if (j == 0) {
                    if (k + i <= d) {
                        chmax(dp[i][(j + 1) % w][k + i], dp[i + 1][j][k] + a[i]);
                    }
                } else{
                    chmax(dp[i][(j + 1) % w][k], dp[i + 1][j][k] + a[i]);
                }
                chmax(dp[i][j][k], dp[i + 1][j][k]);
            }
        }
    }

    for (int j = 0; j < w; ++j) {
        for (int k = 0; k <= d; ++k) {
            chmax(res, dp[1][j][k]);
        }
    }

    cout << res << '\n';

    return (0);
}
accuracy: 1
time_ms: 350
memory_kb: 369340
final_rank: 8

code_snippet: #include <bits/extc++.h>

using namespace std;

#define rep(i,n) for(int i=0;i<(n);++i)
#define reps(i,n) for(int i=1;i<=(n);++i)
#define all(x) begin(x),end(x)
#define Fixed fixed << setprecision(12)
#define updiv(a, b) (((a) + (b) - 1) / (b))
using pii = pair<int,int>;
constexpr int32_t INF  = 0x3f3f3f3f;
constexpr int_fast64_t LINF = 0x3f3f3f3f3f3f3f3fLL;
constexpr int mod1 = 1e9+7;
constexpr int mod2 = 998244353;

template <class Func>
class FixPoint : Func {
public:
    explicit constexpr FixPoint(Func&& f) noexcept : Func(forward<Func>(f)) {}

    template <class... Args>
    constexpr decltype(auto) operator()(Args&&... args) const {
        return Func::operator()(*this, std::forward<Args>(args)...);
    }
};

template <class Func>
static inline constexpr decltype(auto) makeFixPoint(Func&& f) noexcept {
    return FixPoint<Func>{forward<Func>(f)};
}

template<class T, class U> istream& operator>>(istream& is, pair<T, U>& p){ is >> p.first >> p.second; return (is); }
template<class T, class U> ostream& operator<<(ostream& os, pair<T, U>& p){ os << p.first << ' ' << p.second; return (os); }
template<class T> istream& operator>>(istream& is, vector<T>& v){ for (auto &&e : v) is >> e; return (is); }
template<class T> ostream& operator<<(ostream& os, vector<T>& v){ for (auto &&e : v) os << e << ' '; return (os); }

template <class A, class B> inline bool chmax(A &a, const B &b) { return b > a && (a = b, true); }
template <class A, class B> inline bool chmin(A &a, const B &b) { return b < a && (a = b, true); }

template <class T> using max_heap = priority_queue<T>;
template <class T> using min_heap = priority_queue<T, vector<T>, greater<T> >;
template <class A, class B> using umap = unordered_map<A, B>;
template <class T> using uset = unordered_set<T>;

template <class T> using Max_Heap = __gnu_pbds::priority_queue<T, less<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Min_Heap = __gnu_pbds::priority_queue<T, greater<T>, __gnu_pbds::rc_binomial_heap_tag>;
template <class T> using Set = __gnu_pbds::tree<T, __gnu_pbds::null_type, less<T>, __gnu_pbds::rb_tree_tag, __gnu_pbds::tree_order_statistics_node_update>;
template <class K, class V> using Umap = __gnu_pbds::gp_hash_table<K, V>;
template <class T> using Rope = __gnu_cxx::rope<T>;
using Trie = __gnu_pbds::trie<string, __gnu_pbds::null_type, __gnu_pbds::trie_string_access_traits<>, __gnu_pbds::pat_trie_tag, __gnu_pbds::trie_prefix_search_node_update>;

template <class T> void bye(T x){ cout << x << '\n'; exit(0); }
inline int square(int a){ return (a * a); }

constexpr int dx[] = {1,0,-1,0,1,1,-1,-1};
constexpr int dy[] = {0,-1,0,1,1,-1,-1,1};

signed main(){
    cin.tie(nullptr);
    ios_base::sync_with_stdio(false);
    cout.setf(ios_base::fixed);
    cout.precision(12);

    int n, w, d;
    cin >> n >> w >> d;

    d /= 2;

    vector<int> a(n);

    for (int i = 1; i < n; ++i) {
        cin >> a[i];
    }

    // (i, j]
    // vector<vector<int> > val(n, vector<int>(n));
    int val[n][n];

    for (int i = 0; i < n; ++i) {
        int sum = 0;
        min_heap<int> pq;
        for (int j = i + 1; j < n; ++j) {
            pq.push(a[j]);
            if (pq.size() > w) {
                sum -= pq.top();
                pq.pop();
            }
            sum += a[j];
            val[i][j] = sum;
        }
    }
    // vector<vector<int> > dp(n, vector<int>(d + 1, -1));
    int dp[n][d + 1];
    for (int i = 0; i < n; ++i) {
        memset(dp[i], -1, 4 * (d + 1));
    }

    dp[0][0] = 0;
    for (int i = 0; i < n - 1; ++i) {
        int maxv = -1;
        for (int j = 0; j <= d && dp[i][j] != -1; ++j) {
            if (chmax(maxv, dp[i][j])) {
                chmax(dp[i + 1][j], maxv);
                for (int k = i + 1; k < n && j + k <= d; ++k) {
                    chmax(dp[k][j + k], maxv + val[i][k]);
                }
            }
        }
        for (int j = 0; j < d && dp[i + 1][j] != -1; ++j) {
            chmax(dp[i + 1][j + 1], dp[i + 1][j]);
        }
    }

    cout << *max_element(dp[n - 1], dp[n - 1] + d + 1) << '\n';

    return (0);
}
accuracy: 0.11764705882352941
time_ms: 20
memory_kb: 35660
final_rank: 10

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(0);
    int N, W, D;
    cin >> N >> W >> D;
    vector<int> a(N);
    for(int i = 1; i < N; i++)cin >> a[i];
    D /= 2;
    int temp = (N + W - 1) / W;
    D = min(D, temp * (temp + 1) / 2 * W);
    vector<vector<int>> dp(W, vector<int>(D + 1, -(1 << 30)));
    dp[0][D] = 0;
    for(int i = N - 1; i >= 1; i--){
        int r = max(0, D - i + 1);
        vector<int> ndp(r, -(1 << 30));
        for(int j = i; j <= D; j++)ndp[j - i] = max(ndp[j - i], dp[0][j] + a[i]);
        for(int j = 1; j < W; j++){
            for(int k = 0; k <= D; k++){
                dp[j - 1][k] = max(dp[j - 1][k], dp[j][k] + a[i]);
            }
        }
        for(int j = 0; j < r; j++) dp[W - 1][j] = max(dp[W - 1][j], ndp[j]);
    }
    int ans = 0;
    for(int i = 0; i < W; i++)ans = max(ans, *max_element(dp[i].begin(), dp[i].end()));
    cout << ans << '\n';
}
accuracy: 1
time_ms: 150
memory_kb: 5352
final_rank: 1