题解:
首先很贪心的选择
有最大的我们一定会用最大的
然后可以将序列分割。。
就变成了一道模拟题了。。
每个状态记录(h,t,h-have,t-need)
注意一下细节就可以了
代码:
#include <bits/stdc++.h> using namespace std; #define ll long long #define rint register ll #define IL inline #define rep(i,h,t) for (rint i=h;i<=t;i++) #define dep(i,t,h) for (rint i=t;i>=h;i--) #define me(x) memset(x,0,sizeof(x)) const ll N=6e5; ll e,r,n; ll bz[20][N],bz2[20][N],ans,a[N]; ll get_max(ll x,ll y) { ll k=log2(y-x+1); if (bz[k][x]>bz[k][y-(1<<k)+1]) return(bz2[k][x]); else return(bz2[k][y-(1<<k)+1]); } void fz(ll x,ll y,ll pre,ll nxt) { if (x>y) return; ll kk=get_max(x,y); if ((y-kk+1)*r>=nxt) { fz(kk+1,y,r,nxt); if ((pre+(kk-x)*r)>=e) { ans+=e*a[kk]; fz(x,kk-1,pre,e); } else ans+=(pre+(kk-x)*r)*a[kk]; } else { if (pre+(kk-x)*r>=e) ans+=(e-(nxt-(y-kk+1)*r))*a[kk],fz(x,kk-1,pre,e); else ans+=((y-x+1)*r+pre-nxt)*a[kk]; } } int main() { freopen("1.in","r",stdin); freopen("1.out","w",stdout); ios::sync_with_stdio(false); ll T; cin>>T; rep(tt,1,T) { cin>>e>>r>>n; ans=0; me(bz); me(bz2); rep(i,1,n) cin>>bz[0][i],bz2[0][i]=i,a[i]=bz[0][i]; for (ll i=1;i<=19;i++) for (ll j=1;j<=n;j++) if (bz[i-1][j]>bz[i-1][j+(1<<(i-1))]) bz[i][j]=bz[i-1][j],bz2[i][j]=bz2[i-1][j]; else bz[i][j]=bz[i-1][j+(1<<(i-1))],bz2[i][j]=bz2[i-1][j+(1<<(i-1))]; fz(1,n,e,0); cout<<ans<<endl; } return 0; }