1 条题解

  • 0
    @ 2025-8-24 21:42:19

    自动搬运

    查看原文

    来自洛谷,原作者为

    avatar 糪眾脦颰罷
    这个家伙很帅,什么也没有留下

    搬运于2025-08-24 21:42:19,当前版本为作者最后更新于2018-11-05 20:20:04,作者可能在搬运后再次修改,您可在原文处查看最新版

    自动搬运只会搬运当前题目点赞数最高的题解,您可前往洛谷题解查看更多

    以下是正文


    与背包问题类似

    核心内容:

    f[i][j]的意义:坐标为0~i的连续轨道中, 使用成本为j时的最大乐趣值。

    状态转移方程:f[xi+wi][j+ci]=max(f[xi][j]+fi,f[xi+wi][j+ci])(1<=i<=n,0<=j<=b-ci)

    注:需保证此时0~xi+wi均有轨道连着,这个技巧下面会讲到

    基本步骤:

    1.初始化二维数组f的值为**-1**(当没有可行方案时,是输出-1的,这点不知道为什么没翻译出来)并且f[0][0]=0

    2.用结构体储存每根轨道的xi,wi,fi和ci

    3.用sort按xi从小到大排序(方便dp)

    4.dp中,当f[xi][j]不为-1时,进行状态转移,因为f[xi][j]等于-1说明没有轨道从起点一直连到xi(这就保证了0~xi+wi均有轨道连着)

    5.输出f[l][i] (0<=i<=b)中的最大值

    代码一波

    #include<bits/stdc++.h>
    using namespace std;
    int l,n,b,f[1001][1001],ans=-1;
    struct FT{
        int st;
        int ed;
        int f;
        int v;
    };
    FT p[100001];
    bool cmp(FT a1,FT a2){
        return a1.st<a2.st;
    }
    int main(){
        scanf("%d %d %d",&l,&n,&b);
        memset(f,-1,sizeof(f));
        for(int i=1;i<=n;i++){
            int b;
            scanf("%d %d %d %d",&p[i].st,&b,&p[i].f,&p[i].v);
            p[i].ed=p[i].st+b;
        }
        sort(p+1,p+1+n,cmp);
        f[0][0]=0;
        for(int i=1;i<=n;i++){
        	for(int j=0;j<=b-p[i].v;j++){
        		if(f[p[i].st][j]!=-1)f[p[i].ed][j+p[i].v]=max(f[p[i].ed][j+p[i].v],f[p[i].st][j]+p[i].f);
            }
        }
        for(int i=0;i<=b;i++)ans=max(ans,f[l][i]);
        cout<<ans;
        return 0;
    }
    

    提交记录

    104ms / 5.4MB

    代码:0.71KB C++

    • 1

    信息

    ID
    1919
    时间
    1000ms
    内存
    125MiB
    难度
    4
    标签
    递交数
    0
    已通过
    0
    上传者