题解 P2854 【[USACO06DEC]牛的过山车Cow Roller Coaster】
与背包问题类似
核心内容:
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++