题解:AT_abc417_d [ABC417D] Takahashi's Expectation
liluhexuan · · 题解
我不会告诉你这道题比第五题难。
首先,暴力模拟肯定不行,因为时间复杂度会达到
再观察一下,我们会发现如果第
上下起伏的阶段容易实现。我们设
至于初始状态,把所有
接下来我们看一直下降的阶段。在此之前,我们设
首先,我们设
还有,如果
代码:
#include<vector>
#include<iostream>
#include<algorithm>
using namespace std;
#define int long long
const int N=1e4+10,M=1000;
//dp_i_j 从第i个物品开始拿,此时心情为j的最终值
int p[N],a[N],b[N],s[N],dp[N][M+10],f[N*505+10]; //那些数组
signed main(){
ios::sync_with_stdio(0); //快读
cin.tie(0),cout.tie(0);
int n,q;
cin>>n;
for(int i=0;i<=n*505+1;i++) f[i]=1e18; //初始化成最大值
for(int i=1;i<=n;i++){
cin>>p[i]>>a[i]>>b[i];
s[i]=s[i-1]+b[i];
f[s[i-1]+p[i]]=min(f[s[i-1]+p[i]],i); //初始化f数组
}
for(int i=n*505;i>=0;i--) f[i]=min(f[i],f[i+1]); //后缀最小值
for(int j=1;j<=M;j++) dp[n+1][j]=j; //dp预处理
for(int i=n;i>=1;i--){
for(int j=0;j<=M;j++){
if(j<=p[i]) dp[i][j]=dp[i+1][j+a[i]];
else dp[i][j]=dp[i+1][max(0ll,j-b[i])]; //两种情况
}
}
cin>>q;
while(q--){
int x;
cin>>x;
if(x-s[n-1]>p[n]) cout<<max(0ll,x-s[n])<<endl; //特判
else cout<<dp[f[x]][max(0ll,x-s[f[x]-1])]<<endl; //输出答案
}
//n<=p_x+s_x
return 0;
}
时间复杂度可以认为是预处理
最后,再次无耻地求过。