[BZOJ1649]&&[Usaco2006 Dec]Cow Roller Coaster

描述 Description

The cows are building a roller coaster! They want your help to design as fun a roller coaster as possible, while keeping to the budget. The roller coaster will be built on a long linear stretch of land of length L (1 <= L <= 1,000). The roller coaster comprises a collection of some of the N (1 <= N <= 10,000) different interchangable components. Each component i has a fixed length Wi (1 <= Wi <= L). Due to varying terrain, each component i can be only built starting at location Xi (0 <= Xi <= L-Wi). The cows want to string together various roller coaster components starting at 0 and ending at L so that the end of each component (except the last) is the start of the next component. Each component i has a “fun rating” Fi (1 <= Fi <= 1,000,000) and a cost Ci (1 <= Ci <= 1000). The total fun of the roller coster is the sum of the fun from each component used; the total cost is likewise the sum of the costs of each component used. The cows’ total budget is B (1 <= B <= 1000). Help the cows determine the most fun roller coaster that they can build with their budget.

奶牛们正打算造一条过山车轨道.她们希望你帮忙,找出最有趣,但又符合预算的方案. 过山车的轨道由若干钢轨首尾相连,由 x=0 处一直延伸到 X=L(1≤L≤1000) 处.现有 N(1≤N≤10000) 根钢轨,每根钢轨的起点 Xi(0≤Xi≤L- Wi),长度 wi(l≤Wi≤L),有趣指数 Fi(1≤Fi≤1000000),成本 Ci(l≤Ci≤1000) 均己知.请确定一种最优方案,使得选用的钢轨的有趣指数之和最大,同时成本之和不超过 B(1≤B≤1000).

输入格式 InputFormat

Line 1: Three space-separated integers: L, N and B.

Lines 2..N+1: Line i+1 contains four space-separated integers, respectively: Xi, Wi, Fi, and Ci.

第 1 行输入 L,N,B,接下来 N 行,每行四个整数 Xi,wi,Fi,Ci.

输出格式 OutputFormat

Line 1: A single integer that is the maximum fun value that a roller-coaster can have while staying within the budget and meeting all the other constraints. If it is not possible to build a roller-coaster within budget, output -1.

样例输入 SampleInput

10 50 100
5 5 86837 8
2 8 682046 8
1 6 877477 10
1 6 464707 5
2 7 210984 4
2 6 7935 8
4 3 658751 10
2 3 954705 4
3 1 801115 3
1 2 722853 9
0 8 729064 10
8 1 283734 1
3 5 54777 9
0 6 685984 9
5 2 484932 3
1 4 277847 3
1 3 709448 2
8 1 814029 4
3 3 390595 2
1 2 686243 10
1 8 86507 5
5 3 468759 8
2 3 691596 4
3 6 307679 1
2 2 520042 6
3 4 22081 7
2 7 503798 10
3 5 353212 7
7 3 831889 7
5 4 892482 4
7 3 285513 8
3 4 753160 7
1 2 930559 10
3 3 701662 10
0 3 323221 8
7 1 321061 3
2 6 292088 9
4 1 577314 5
1 5 458422 9
1 9 797724 8
0 4 730674 1
8 1 88293 10
2 2 653669 4
0 3 907305 9
0 1 10002 8
0 7 178440 6
7 2 789848 7
5 2 357092 9
4 2 789530 10
5 2 442766 5

样例输出 SampleOutput

3635811

来源 Source

Silver


BZOJ 1649


代码 Code

二维背包。f[i][j] 表示长度到 i 费用为 j 的最大有趣指数,初始化为 \(-\infty\),状态转移方程为 \[f[a[i].x+a[i].w][j+a[i].c]=Max\lbrace \begin{aligned} &f[a[i].x+a[i].w][j+a[i].c] \\\\ &f[a[i].x][j]+a[i].fun \end{aligned} \rbrace.\]

#include <stdio.h>
#include <iostream>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;
const int inf=0x7fffffff/27.11;
struct path
{
    int x,w,fun,c;
    bool operator < (const path &temp) const
    {
        if (x!=temp.x) return x<temp.x;
        else return w<temp.w;
    }
}a[10005];
int f[1005][1005];
int i,j,t,n,m,l,r,k,z,y,x;
inline int read()
{
    int x=0;char ch=getchar();
    while (ch<'0' || ch>'9') ch=getchar();
    while (ch>='0' && ch<='9') x=x*10+ch-'0',ch=getchar();
    return x;
}
int main()
{
    l=read();n=read();int b=read();
    for (i=1;i<=n;i++) a[i].x=read(),a[i].w=read(),a[i].fun=read(),a[i].c=read();
    sort(a+1,a+n+1);
    for (i=0;i<=l;i++) for (j=0;j<=b;j++) f[i][j]=-inf;f[0][0]=0;
    for (i=1;i<=n;i++) if (a[i].x+a[i].w<=l)
    {
        for (j=0;j<=b-a[i].c;j++)
        {
            f[a[i].x+a[i].w][j+a[i].c]=max(f[a[i].x+a[i].w][j+a[i].c],f[a[i].x][j]+a[i].fun);
        }
    }
    int ans=-1;
    for (i=0;i<=b;i++) ans=max(ans,f[l][i]);
    printf("%dn",ans);
    return 0;
}