题意:初始有m能量,需要跑完n个区域,每个区域都有三种模式,快模式 ,需要t1[i]时间,f1[1]能量,普通模式,需要t2[i]时间,不消耗能量,慢跑模式,需要t3[i]时间,恢复f2[i]能量,求跑完n个区域最短需要多少时间?
dp,需要注意补充能量后不能超过m。
#include <iostream>
#include <cstdio>
#include <algorithm>
#include <string.h>
using namespace std;
const int MAXN = 115;
int t1[MAXN],t2[MAXN],t3[MAXN],f1[MAXN],f2[MAXN];
int dp[MAXN][MAXN];
//dp[i][j]表示能量为j时跑完i-n个区域需要的最短时间
int main(void){
int t;
scanf("%d",&t);
while(t--){
int n,m;
memset(dp,0,sizeof(dp));
scanf("%d%d",&n,&m);
for(int i = 1; i <= n; i++){
scanf("%d%d%d%d%d",&t1[i],&t2[i],&t3[i],&f1[i],&f2[i]);
}
//从右向左dp,对i为n时进行初始化,跑最后一个区域时
//体力大于跑快跑道所需的体力时,跑快跑道
//否则就选择普通模式,因为最后一个区域选择恢复体力无意义
for(int j = 0; j <= m; j++){
if(j >= f1[n]){
dp[n][j] = t1[n];
}
else{
dp[n][j] = t2[n];
}
}
for(int i = n; i >= 1; i--){
for(int j = 0; j <= m; j++){
//普通模式
dp[i][j] = dp[i + 1][j] + t2[i];
//跑快模式
if(j >= f1[i]){
dp[i][j] = min(dp[i][j],dp[i + 1][j - f1[i]] + t1[i]);
}
//慢模式恢复体力,体力最多恢复到m
if(j + f2[i] <= m){
dp[i][j] = min(dp[i][j],dp[i + 1][j + f2[i]] + t3[i]);
}
else{
dp[i][j] = min(dp[i][j],dp[i + 1][m] + t3[i]);
}
}
}
printf("%d\n",dp[1][m]);
}
return 0;
}