P2854 [USACO06DEC] Cow Roller Coaster S

纯粹的發表於2024-03-26

原題連結

題解

1.當沒有花費限制的時候,我們可以將其抽象為簡單的揹包問題
2.如果有了花費限制,那麼我們就再加一維條件

3.如果一個線段能用,那麼它前面一定是鋪滿的,那我們令線段按起點排序,透過某種運算,保證放這個線段時,前面的線段組成是最優的
比如在 \(i\) 點結尾位置花費 \(j\) 所達到的最優值,這個最優值與後面線段怎麼擺無關,所以可以存起來減少重複運算,這也是dp的核心

code

#include<bits/stdc++.h>
using namespace std;
struct node
{
    int start,len,v,c;
}seg[10005];
bool cmp(node a,node b)
{
    if(a.start!=b.start) return a.start<b.start;
    return a.len<b.len;
}

int f[1005][1005]={0};
int main()
{
    int l,n,b;
    cin>>l>>n>>b;
    for(int i=1;i<=n;i++)
    {
        cin>>seg[i].start>>seg[i].len>>seg[i].v>>seg[i].c;
    }

    sort(seg+1,seg+1+n,cmp);

    for(int i=0;i<=l;i++)
    {
        for(int j=1;j<=n;j++)
        {
            int start=seg[j].start;
            if(start==i)
            {
                int ends=start+seg[j].len;
                if(i==0) f[ends][seg[j].c]=max(seg[j].v,f[ends][seg[j].c]);
                for(int k=seg[j].c;k<=b;k++) if(f[start][k-seg[j].c]) f[ends][k]=max(f[start][k-seg[j].c]+seg[j].v,f[ends][k]);
            }
        }
    }

    int ans=0;
    for(int i=1;i<=b;i++) ans=max(ans,f[l][i]);
    cout<<(ans?ans:-1);
    return 0;
}

相關文章