思路:
1.每份工作只有做和不做,问最大利润,自然就能想到0/1背包问题;
2.设表示用天的时间,在前个工程中所能获得的最大利润,设为第个工作,、和分别代表利润、花费的时间和截止日期,则我们有
和普通背包不同的就是在日期超过时我们无法通过完成第份工作来达到第天,因此有第三行的递推式;
3.相同的几个工作,我们肯定需要先完成截止日期近的工作,因此需要对数组内容按截止日期进行排序;
代码:
#pragma GCC optimize(2)
#include<bits/stdc++.h>
using namespace std;
const int maxn=52;
int n,lmt=0;
vector<int> dp[maxn];
struct work{int pro,cost,ddl;}wk[maxn];
void solve(){
for(int i=0;i<=n;i++) dp[i].resize(lmt+1);
sort(wk+1,wk+n+1,[](const work& w1,const work& w2){return w1.ddl<w2.ddl;});
for(int i=1;i<=n;i++){
for(int j=1;j<=lmt;j++){
if(j>=wk[i].cost&&j<=wk[i].ddl)
dp[i][j]=max(dp[i-1][j],dp[i-1][j-wk[i].cost]+wk[i].pro);
else if(j<wk[i].cost) dp[i][j]=dp[i-1][j];
else dp[i][j]=max(dp[i-1][j],dp[i][j-1]);
}
}
cout<<dp[n][lmt];
}
int main(){
// freopen("Sakura.txt","r",stdin);
cin>>n;
for(int i=1;i<=n;i++){
cin>>wk[i].pro>>wk[i].cost>>wk[i].ddl;
lmt=max(lmt,wk[i].ddl);
}
solve();
return 0;
}