显然,每个法力池最终能收集到的法力只与这个法力池最终被收集到的时间有关。
对于一组询问 \((s,e)\),假设我们经过了 \(k\) 个法力池,我们钦定最终被收集到的时间从后到前分别是 \(e=a_1,a_2,\cdots,a_k\),那么最大法力值为 \(\sum\limits_{i=1}^kc_{a_i}·\sum\limits_{j=2}^i(s-dis(a_j,a_{j-1}))\),当然,由于只有 \(s\) 秒的限制,所以要求 \(\sum\limits_{i=2}^kdis(a_i,a_{i-1})\le s\),但是我们发现这个限制其实没有用,因为减到零以下对答案贡献为负数,肯定不优。因此我们抛开 \(s\) 的限制直接状压 \(dp\):\(dp_{S,t}\) 表示目前包含了 \(S\) 中的法力池,当前在 \(t\) 的最大收益,那么有 \(dp_{S,t}-sumc_S·dis(x,t)\to dp_{S\cup x,x}\),其中 \(sumc_S\) 表示 \(S\) 中的法力值的 \(c_i\) 之和,最终答案即为 \(\max_{e\in S}\max_{x\in S}\{sumc_S·s+dp_{S,x}\}\),初始值 \(dp_{\{e\},e}=0\),其他全为 \(-\infty\)。然后你发现这个 DP 过程只与 \(e\) 有关,与 \(s\) 无关,所以对每个 \(e\) 做遍 DP 然后建个凸包即可。
时间复杂度 \(O(n^3+2^nn^2+q\log q)\)。
typedef __int128_t i128;
const int MAXN=18;
const int MAXP=262144;
const int MAXM=2e5;
int n,m,a[MAXN+5];vector<pii>g[MAXN+5],qv[MAXN+5];
i128 sum[MAXP+5],dp[MAXP+5][MAXN+5],dis[MAXN+5][MAXN+5],res[MAXM+5];
ld slope(pair<i128,i128>x,pair<i128,i128> y){return 1.0*(y.se-x.se)/(y.fi-x.fi);}
void _print(i128 x){if(!x)return;_print(x/10);putchar(x%10+'0');}
void print(i128 x){if(!x)putchar('0');else _print(x);}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)scanf("%d",&a[i]);
memset(dis,63,sizeof(dis));for(int i=1;i<=n;i++)dis[i][i]=0;
for(int i=1,u,v,w;i<=m;i++){scanf("%d%d%d",&u,&v,&w);chkmin(dis[u][v],w);}
for(int k=1;k<=n;k++)for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)
chkmin(dis[i][j],dis[i][k]+dis[k][j]);
for(int i=0;i<(1<<n);i++)for(int j=1;j<=n;j++)if(i>>(j-1)&1)sum[i]+=a[j];
memset(dp,63,sizeof(dp));
for(int i=1;i<=n;i++)dp[1<<i-1][i]=0;
for(int i=0;i<(1<<n);i++)for(int j=1;j<=n;j++)if(i>>(j-1)&1)
for(int k=1;k<=n;k++)if((~i>>(k-1)&1)&&dis[j][k]!=dis[0][0])
chkmin(dp[i|(1<<k-1)][k],dp[i][j]+1ll*dis[j][k]*sum[i]);
int qu;scanf("%d",&qu);
for(int i=1,x,y;i<=qu;i++){scanf("%d%d",&x,&y);qv[y].pb(mp(x,i));}
for(int i=1;i<=n;i++){
vector<pair<i128,i128> >vec,nvec,pt;
for(int j=0;j<(1<<n);j++)if((j>>(i-1)&1)&&dp[j][i]!=dp[0][0])
vec.pb(mp(sum[j],dp[j][i]));
sort(vec.begin(),vec.end());
for(int l=0,r;l<vec.size();l=r){
i128 mn=dp[0][0];r=l;
while(r<vec.size()&&vec[r].fi==vec[l].fi)chkmin(mn,vec[r].se),++r;
nvec.pb(mp(vec[l].fi,mn));
}
for(auto p:nvec){
while(pt.size()>=2&&slope(pt[pt.size()-2],pt.back())>slope(pt.back(),p))pt.ppb();
pt.pb(p);
}
sort(qv[i].begin(),qv[i].end());int cur=0;
for(pii p:qv[i]){
while(cur+1<pt.size()&&slope(pt[cur],pt[cur+1])<p.fi)++cur;
res[p.se]=pt[cur].fi*p.fi-pt[cur].se;
}
}
for(int i=1;i<=qu;i++)print(res[i]),putchar('\n');
return 0;
}
标签:洛谷,法力,pt,int,sum,P9020,USACO23JAN,MAXN,dp
From: https://www.cnblogs.com/tzcwk/p/luogu-P9020.html