洛谷 P3983 赛斯石(赛后强化版) 题解

题目链接

洛谷 P3983 赛斯石(赛后强化版)

思路分析

首先,我们发现,对于塞斯石,它们既可以一个放进一条船,也可以几个放进一条船,每一块的重量也不同,不好考虑。但是,我们发现,塞斯石都需要通过载重量为 \(1\operatorname{si}\sim 10\operatorname{si}\) 的船只进行运输。所以,可以转而考虑研究船。

对于每条船,我们可以先预处理出组一条这种船最大的利润。然后,就变成了选择一些船使利润最大,考虑用背包 DP 解决。以塞斯石的重量,即船的载重量之和为背包容量,每种船的载重量为代价,能带来的利润为价值。

同时,我们还要预处理出每条船的利润。我们以 \(1\operatorname{si}\sim 10\operatorname{si}\) 的塞斯石为物品再跑一个完全背包即可。

代码如下,时间复杂度 \(O(need)\)

代码呈现

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;

const int N=1e5+10;
int need;
int a[15],b[11]={0,1,3,5,7,9,10,11,14,15,17};
ll dp[N];

int main(){
    scanf("%d",&need);
    for (int i=1;i<=10;++i) scanf("%d",a+i);
    for (int i=1;i<=10;++i){
        for (int j=i;j<=10;++j) dp[j]=max(dp[j],dp[j-i]+a[i]);
    }
    for (int i=1;i<=10;++i) dp[i]-=b[i];
    for (int i=1;i<=10;++i){
        for (int j=i;j<=need;++j) dp[j]=max(dp[j],dp[j-i]+dp[i]);
    }
    ll ans=0;
    for (int i=1;i<=need;++i) ans=max(ans,dp[i]);
    printf("%lld",ans);
    return 0;
}
posted @ 2026-04-26 19:28  CodingJuRuo  阅读(7)  评论(0)    收藏  举报