题解:本题是经典的dp题,主要考查dp。
简要题意:奶牛落在D米深井,每个垃圾扔下的时间t以及每个垃圾堆放的高度h和吃进该垃圾能维持生命的时间f,奶牛有10小时的能量。求最早什么时候可以爬出或输出卡门最长可以存活多长时间。
1.dp:设
f
[
i
]
[
j
]
f[i][j]
f[i][j]表示前i个垃圾在到达j的高度时剩余的最大血量,则有两种情况:
1.吃:
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
]
[
j
]
,
f
[
i
−
1
]
[
j
]
−
(
t
[
i
]
.
t
i
m
e
−
t
[
i
−
1
]
.
t
i
m
e
)
+
t
[
i
]
.
a
n
s
)
f[i][j]=max(f[i][j],f[i-1][j]-(t[i].time-t[i-1].time)+t[i].ans)
f[i][j]=max(f[i][j],f[i−1][j]−(t[i].time−t[i−1].time)+t[i].ans)
2.不吃:
f
[
i
]
[
j
]
=
m
a
x
(
f
[
i
]
[
j
]
,
f
[
i
−
1
]
[
j
−
t
[
i
]
.
h
]
−
t
[
i
]
.
t
i
m
e
+
t
[
i
−
1
]
.
a
n
s
)
f[i][j]=max(f[i][j],f[i-1][j-t[i].h]-t[i].time+t[i-1].ans)
f[i][j]=max(f[i][j],f[i−1][j−t[i].h]−t[i].time+t[i−1].ans)
但是要注意,能完成这些操作奶牛必须活着,所以加上判断:
f
[
i
−
1
]
[
j
]
−
t
[
i
]
.
t
i
m
e
+
t
[
i
−
1
]
.
t
i
m
e
>
=
0
f[i-1][j]-t[i].time+t[i-1].time>=0
f[i−1][j]−t[i].time+t[i−1].time>=0
代码如下:
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
int f[101][1001];
struct N
{
int time,ans,h;
}t[2333];
int n,m,ans=0;
int cmp(N a,N b)
{
return a.time<b.time;
}
int main()
{
cin>>n>>m;
for(int i=1;i<=m;i++)
cin>>t[i].time>>t[i].ans>>t[i].h;
sort(t+1,t+m+1,cmp);
memset(f,-0x3f3f,sizeof(f));
f[0][0]=10;
for(int i=1;i<=m;i++)
for(int j=0;j<=n;j++)
{
if(f[i-1][j]-t[i].time+t[i-1].time>=0)
f[i][j]=max(f[i][j],f[i-1][j]-t[i].time+t[i-1].time+t[i].ans);
if(f[i-1][j-t[i].h]-t[i].time+t[i-1].time>=0&&j-t[i].h>=0) //这里注意,时间不可能是负数
{
f[i][j]=max(f[i][j],f[i-1][j-t[i].h]-t[i].time+t[i-1].time);
if(j==n){cout<<t[i].time<<endl;cin>>n;return 0;}//直接找到最优解
}
}
for(int i=0;i<=m;i++)
for(int j=0;j<=n;j++)
if(f[i][j]!=-0x3f3f)
ans=max(ans,f[i][j]+t[i].time);
cout<<ans<<endl;
return 0;
}