思路
和01背包有点像,但是约束条件很多,首先设f[i][j],表示起点为i,不超过j的花费的最大解
我们发现对于每一个轨道来说,i是一定的,它对应能更新的点,或者说能影响到的点也是一定的,就是起点是它结尾的点,所以我们只要枚举一下所有的点,让他去更新一下其他点就可以了,前提是这个点的所有可能都已经被算过了。所以我们再枚举之前,要对每个点按照起点的顺序排序
代码
#include <cstring>
#include <algorithm>
#include <iostream>
using namespace std;
const int N=10010;
typedef long long ll;
ll f[1010][1010];
ll len,cost,n;
struct Node{
ll w;
ll x;
ll f;
ll c;
}a[N];
int cmp(Node a,Node b)
{
if (a.x==b.x)
return a.w<b.w;
return a.x<b.x;
}
int main(){
cin >> len >> n >> cost;
for(int i=0;i<n;i++)
scanf("%d%d%d%d",&a[i].x,&a[i].w,&a[i].f,&a[i].c);
sort(a,a+n,cmp);
memset(f,-1,sizeof f);
f[0][0]=0;
for(int i=0;i<n;i++){
for(int j=a[i].c;j<cost;j++){
if(f[a[i].x][j-a[i].c]!=-1){
f[a[i].x+a[i].w][j]=max(f[a[i].x+a[i].w][j],f[a[i].x][j-a[i].c]+a[i].f);
}
}
}
ll maxx=-1;
for(int i=0;i<=cost;i++)
maxx=max(maxx,f[len][i]);
cout << maxx;
}