제출 #216949

#제출 시각아이디문제언어결과실행 시간메모리
216949someone_aaK개의 묶음 (IZhO14_blocks)C++17
53 / 100
8 ms896 KiB
#include <bits/stdc++.h> #define ll long long #define pb push_back #define mp make_pair using namespace std; const int maxn = 110; const int maxk = 110; int n, k; int dp[maxn][maxk]; int a[maxn]; int tree[maxk][4*maxn]; void build(int tree_ind, int li=0, int ri=n, int index=1) { if(li == ri) tree[tree_ind][index] = INT_MAX; else { int mid = (li + ri) / 2; build(tree_ind, li, mid, 2*index); build(tree_ind, mid+1, ri, 2*index+1); tree[tree_ind][index] = min(tree[tree_ind][2*index], tree[tree_ind][2*index+1]); } } void update(int tree_ind, int ind, int val, int li=0, int ri=n, int index=1) { if(li==ri) { tree[tree_ind][index] = val; } else { int mid = (li + ri) / 2; if(ind <= mid) update(tree_ind, ind, val, li, mid, 2*index); else update(tree_ind, ind, val, mid+1, ri, 2*index+1); tree[tree_ind][index] = min(tree[tree_ind][2*index], tree[tree_ind][2*index+1]); //cout<<"For the range: "<<li<<" "<<ri<<" -> "<<tree[tree_ind][index]<<"\n"; } } int query(int tree_ind, int ql, int qr, int li=0, int ri=n, int index=1) { //cout<<"Discovering "<<li<<" "<<ri<<" with val "<<tree[tree_ind][index]<<" at "<<index<<"\n"; if(li > qr || ri < ql) return INT_MAX; else if(li >= ql && ri <= qr){ //cout<<"Ulaza "<<li<<" "<<ri<<" - "<<tree[tree_ind][index]<<"\n"; return tree[tree_ind][index]; } else { int mid = (li + ri) / 2; return min(query(tree_ind, ql, qr, li, mid, 2*index), query(tree_ind, ql, qr, mid+1, ri, 2*index+1)); } } int prev_ind[maxn]; void preprocess() { deque<pair<int,int> > dq; dq.push_back(mp(a[1], 1)); prev_ind[1] = -1; for(int i=2;i<=n;i++) { while(dq.size() > 0 && dq.back().first <= a[i]) { dq.pop_back(); } if(dq.size() == 0) prev_ind[i] = -1; else prev_ind[i] = dq.back().second; dq.push_back(mp(a[i], i)); } } int main() { cin>>n>>k; int prefmax = 0; for(int i=1;i<=k;i++){ build(i); } for(int i=1;i<=n;i++) { cin>>a[i]; prefmax = max(prefmax, a[i]); dp[i][1] = prefmax; update(1, i, dp[i][1]); } preprocess(); for(int i=2;i<=n;i++) { for(int d=2;d<=k;d++) { if(i < d) continue; if(prev_ind[i] == -1) { dp[i][d] = query(d-1, d-1, i-1) + a[i]; //cout<<i<<": "<<query(d-1, d-1, i-1)<<" "<<dp[i][d]<<"\n"; } else { dp[i][d] = INT_MAX; if(prev_ind[i] >= d) dp[i][d] = dp[prev_ind[i]][d]; dp[i][d] = min(dp[i][d], query(d-1, max(prev_ind[i], d-1), i-1) + a[i]); } update(d, i, dp[i][d]); } } cout<<dp[n][k]<<"\n"; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...