在一个水平的数轴上有一个自爆小卡车和一个恐怖分子,自爆卡车初始的坐标为 0,恐怖分子的坐标为 n,自爆卡车在启动后以 1 坐标每秒的速度向恐怖分子移动,在遇到恐怖分子的瞬间爆炸,造成的伤害为自爆卡车运行时间。现在你有 m 个方向转换器位于 m 个不同的坐标上。你可以重复的使用方向转换器(在该坐标安装方向转换器,拆除方向转换器),使得自爆卡车到达该点时,方向取反,相反方向移动。方向转换器的安装与拆除时间忽略不计。这样有可能使得自爆卡车无限的运行下去,为了避免这种情况,自爆卡车有一个自爆最大时间 t,即 t 秒后会自动爆炸,问自爆卡车会对恐怖分子造成最大的伤害是多少。
第一行一个整数 T,表示有 T 组测试数据
对于每组测试数据:第一行三个整数 n,m,t
第二行给出m个不同的整数,表示可安装拆除方向转换器的坐标 xi
1≤t≤1e4,1≤m<n≤2e5,1≤t≤2e5,1≤xi<n,t 组数据 n 的总和小于等于 2e5,t 的总和小于等于 2e5。
思路:完全背包。
死因:TLE
#include<bits/stdc++.h>
using namespace std;
int T,n,m,t;
int x[200005],a[200005],f[200005];
int ans;
int main(){
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&n,&m,&t);
t-=n;
for(int i=1;i<=m;++i)
scanf("%d",&x[i]);
sort(x+1,x+1+m);
for(int i=1;i<m;++i)
a[i]=(x[i+1]-x[i])*2;
for(int i=1;i<m;++i)
for(int j=a[i];j<=t;j++)
f[j]=max(f[j-a[i]]+a[i],f[j]);
for(int i=0;i<=t;++i)
ans=max(ans,f[i]),f[i]=0;
ans+=n;
printf("%d\n",ans);
ans=0;
}
return 0;
}