背包型动归。
传送门:GO
设f[i][j]表示第i个点高度为j的最大生命值。
如果吃掉:
f[i][j]=max(f[i-1][j]+t[i]-dis[i],f[i][j])
如果垫脚:
f[i][j]=max(f[i-1][j-h[i]]-dis[i],f[i][j])
如果有一种情况能让它走出去,就直接输出,
如果生命值小于0了,就直接跳过即可。
代码:
1 #include<bits/stdc++.h> 2 using namespace std; 3 int read(){ 4 int x=0,f=1; 5 char c=getchar(); 6 while(!isdigit(c)){ 7 if(c=='-') f=-1; 8 c=getchar(); 9 } 10 while(isdigit(c)){ 11 x=x*10+c-'0'; 12 c=getchar(); 13 } 14 return x*f; 15 } 16 const int N=110; 17 int d,n,ans; 18 struct bin{int time,life,h;}a[N]; 19 bool cmp(bin t1,bin t2){return t1.time<t2.time;} 20 int t(int y){return a[y].time-a[y-1].time;} 21 int dp[N][N]; 22 int main(){ 23 d=read(); 24 n=read(); 25 for(int i=1;i<=n;i++){a[i]=(bin){read(),read(),read()};} 26 sort(a+1,a+n+1,cmp); 27 memset(dp,-0x3f,sizeof(dp)); 28 dp[0][0]=10; 29 ans=-0x7f; 30 for(int i=1;i<=n;i++){ 31 for(int j=d;j>=0;j--){ 32 if(dp[i-1][j]-t(i)<0) continue; 33 if(j+a[i].h>=d){ 34 printf("%d",a[i].time); 35 return 0; 36 } 37 dp[i][j+a[i].h]=max(dp[i][j+a[i].h],dp[i-1][j]-t(i)); 38 dp[i][j]=max(dp[i][j],dp[i-1][j]-t(i)+a[i].life); 39 } 40 ans=max(ans,dp[i][0]+a[i].time); 41 } 42 printf("%d",ans); 43 return 0; 44 }