专栏文章
题解:P14300 [JOI2023 预选赛 R2] 货物列车 / Freight Train
P14300题解参与者 4已保存评论 8
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 8 条
- 当前快照
- 1 份
- 快照标识符
- @minifv1f
- 此快照首次捕获于
- 2025/12/02 02:56 3 个月前
- 此快照最后确认于
- 2025/12/02 02:56 3 个月前
给一个 的写法。
前言
为了方便,把 的物品下标换到 ,且将 减 , 除以 ,这样可以将距离从 变为 ,显然对答案无影响。
思路
考虑朴素 ,设计 表示考虑前 个数,用了 的路程的最大价值,那其实就是一个空间为 的背包,每个物品体积为 ,价值是转移区间里前 大的数,记 表示区间 中前 大的数,转移显然:
暴力转移复杂度 ,考虑优化。
复杂度 ,注意要特判 的情况。
代码
注意不要开
CPPlong long,空间会炸。#include<bits/stdc++.h>
using namespace std;
const int N=460;
int n,w,d;
int f[N][N*N],ans[N][N],a[N];
int tmp[N];
int query(int l,int r){
int ans=0,c=0;
for(int i=l;i<=r;i++) tmp[++c]=a[i],ans+=a[i];
if(c<=w) return ans;
sort(tmp+1,tmp+c+1);
ans=0;
for(int i=c;i>=c-w+1;i--) ans+=tmp[i];
return ans;
}
void solve(int i,int l,int r,int L,int R){
if(l>r) return;
int mid=l+r>>1,mx=0,k=0;
for(int j=L;j<=R;j++)
if(f[j][mid-i]+ans[j+1][i]>mx){
mx=f[j][mid-i]+ans[j+1][i];
k=j;
}
f[i][mid]=mx;
solve(i,l,mid-1,L,k);
solve(i,mid+1,r,k,R);
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0),cout.tie(0);
cin>>n>>w>>d;
--n,d/=2;
for(int i=1;i<=n;i++) cin>>a[i];
if(w==1){
int ans=0;
for(int i=1;i<=n;i++)
for(int j=0;j<=d;j++)
if(j>=i) f[i][j]=max(f[i-1][j],f[i-1][j-i]+a[i]),ans=max(ans,f[i][j]);
else f[i][j]=f[i-1][j];
return cout<<ans,0;
}
for(int l=1;l<=n;l++)
for(int r=l;r<=n;r++)
ans[l][r]=query(l,r);
for(int i=1;i<=n;i++) solve(i,i,d,0,i-1);
int ans=0;
for(int i=1;i<=n;i++)
for(int j=i;j<=d;j++)
ans=max(ans,f[i][j]);
cout<<ans;
return 0;
}
相关推荐
评论
共 8 条评论,欢迎与作者交流。
正在加载评论...