dpi,j 表示选前 i 个物品,时间为 j 的最大美值.
choj表示时间 j 内获取最大美值看了几次树 i .
状态转移如下情况:
2.(j>=ti)
dpi,j=dpi−1,j−ti+ci,choj=1;4.( choj<pi || pi==0 && j>=ti)
dpi,j=dpi,j−ti+ci,choj=choj−ti+1;在这之中取最大值并且更新 choj 用于后续判断
代码如下:
#include<bits/stdc++.h>
using namespace std;
int dp[10004][1003];
int cho[1003];
int t[10004],c[10004],p[10004];
int sh,sm,eh,em;
int n,m;
void solve(){
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
if(dp[i][j]<dp[i][j-1]){
dp[i][j]=dp[i][j-1];
cho[j]=cho[j-1];
}
if(j>=t[i]){
if(!p[i] || cho[j-t[i]]<p[i]){
if(dp[i][j]<dp[i][j-t[i]]+c[i]){
dp[i][j]=dp[i][j-t[i]]+c[i];
cho[j]=cho[j-t[i]]+1;
}
}
if(dp[i][j]<=dp[i-1][j-t[i]]+c[i]){
dp[i][j]=dp[i-1][j-t[i]]+c[i];
cho[j]=1;
}
}
if(dp[i][j]<=dp[i-1][j]){
dp[i][j]=dp[i-1][j];
cho[j]=0;
}
}
}
}
int main(){
scanf("%d:%d %d:%d",&sh,&sm,&eh,&em);
cin>>n;
if(em-sm<0)m-=60;;
m+=((em-sm)+60)%60;
m+=60*(((eh-sh)+24)%24);
for(int i=1;i<=n;i++){
cin>>t[i]>>c[i]>>p[i];
}
solve();
cout<<dp[n][m]<<'\n';
return 0;
}