额,为了提升一下自己动规的能力,就找的了这道题。
题目意思很简单,就是给你几条边让你铺满 [ 0.. L ] [0..L] [0..L],在花费不超过 B B B的条件下,求最大价值 V V V
dp状态的定义
f
[
i
]
[
j
]
表
示
铺
设
到
第
i
个
位
置
,
总
花
费
为
j
,
能
获
得
的
最
大
价
值
f[i][j]表示铺设到第i个位置,总花费为j,能获得的最大价值
f[i][j]表示铺设到第i个位置,总花费为j,能获得的最大价值
初始化
因为是要求最大价值V,所以要把数组初始化为最小值,但是最大的价值肯定是
>
=
0
>=0
>=0,所以数组一开始并不用管
dp转移前准备
因为位置
i
i
i是从小到大枚举的,那么
f
[
i
]
[
j
]
f[i][j]
f[i][j]必定是从
f
[
k
]
[
p
]
(
k
<
i
)
(
p
<
=
j
)
f[k][p](k<i)(p<=j)
f[k][p](k<i)(p<=j)转移过来,所以我们要在输入的时候建立边,因为输入的是数据是
初
始
点
,
长
度
,
价
值
,
代
价
初始点,长度,价值,代价
初始点,长度,价值,代价,所以从终点建一条边到起始点
转移
f
[
i
]
[
j
]
=
m
a
x
(
f
[
t
o
]
[
j
−
e
d
g
e
[
i
]
.
w
]
+
e
d
g
e
[
i
]
.
v
a
l
,
f
[
i
]
[
j
]
)
f[i][j]=max(f[to][j-edge[i].w]+edge[i].val,f[i][j])
f[i][j]=max(f[to][j−edge[i].w]+edge[i].val,f[i][j])
在这个状态下必须从上一段路转移过来
细节
因为铁轨一定是要连续的并要从0开始铺着过来,所以要判断一下,不然就会挂成30pts,别问我怎么知道的
i f ( d p [ t o ] [ j − e d g e [ k ] . w ] ∣ ∣ t o = = 0 ) 转 移 if(dp[to][j-edge[k].w]||to==0){转移} if(dp[to][j−edge[k].w]∣∣to==0)转移
#include<bits/stdc++.h>
#define maxn 10010
#define maxm 1010
#define int long long
using namespace std;
inline int read()
{
int res=0,f=1;char ch=getchar();
while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
while(isdigit(ch)){res=(res<<1)+(res<<3)+(ch&15);ch=getchar();}
return res*f;
}
int L,n,B;
int head[maxn],tot;
struct node{
int to,next,val,w;
}edge[maxn];
inline void add(int x,int y,int w,int val)//链式前向星建边
{
edge[++tot].to=y;
edge[tot].next=head[x];
edge[tot].w=w;
edge[tot].val=val;
head[x]=tot;
}
int ans=0;
int dp[maxn][maxm];
signed main()
{
memset(head,-1,sizeof(head));
L=read();n=read();B=read();
for(int i=1;i<=n;i++)
{
int u,v,f,c;u=read();v=read();f=read();c=read();
add(u+v,u,c,f);
}
for(int i=0;i<=L;i++)
{
for(int j=0;j<=B;j++)
{
for(int k=head[i];k!=-1;k=edge[k].next)
{
if(j-edge[k].w>=0)
{
int to=edge[k].to;
if(!dp[to][j-edge[k].w]&&to)continue;
dp[i][j]=max(dp[to][j-edge[k].w]+edge[k].val,dp[i][j]);
}
}
}
}
/* for(int i=1;i<=L;i++)
{
for(int j=1;j<=B;j++)
cout<<dp[i][j]<<" ";
cout<<endl;
}*/
for(int i=0;i<=B;i++)ans=max(ans,dp[L][i]);//答案可能所有的花费中
if(!ans)cout<<-1;
else cout<<ans;
return 0;
}