版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/lidengdengter/article/details/89890594
拿每件物品耗时t ,价值为w 当总时超过d则不能拿,问最大价值以及取物号(物品标号)。
01背包问题,用dp[i][j]代表拿第i个物品用时j的价值,则
拿:dp[i][j] = max( dp[i-1][j] , dp[i-1][j-t] + w ) ;
不拿:dp[i][j] = dp[i-1][j] 。
#include<cstdio>
#include<vector>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=105;
struct node{
int id;
int t,d,w;
}p[N];
int dp[105][2005];
bool vis[105][2005];
vector<int>ans;
bool cmp1(node a,node b){
return a.d<b.d;
}
int main(){
int n,maxd;
while(~scanf("%d",&n)){
ans.clear();
memset(dp,0,sizeof(dp));
memset(vis,false,sizeof(vis));
maxd=0;
for(int i=1;i<=n;i++){
scanf("%d%d%d",&p[i].t,&p[i].d,&p[i].w);
p[i].id=i;
maxd=max(maxd,p[i].d);
}
sort(p+1,p+1+n,cmp1);
int pos;
for(int i=1;i<=n;i++){
pos=0;
for(int j=0;j<=maxd;j++){
if(j>=p[i].t&&j<p[i].d&&dp[i-1][j]<dp[i-1][j-p[i].t]+p[i].w){
dp[i][j]=dp[i-1][j-p[i].t]+p[i].w;
vis[i][j]=true;
}
else
dp[i][j]=dp[i-1][j];
if(dp[i][pos]<dp[i][j]) //one best time
pos=j;
}
}
printf("%d\n",dp[n][pos]);
for(int i=n;i>0;i--)
if(vis[i][pos]){ //save
ans.push_back(p[i].id);
pos-=p[i].t;
}
printf("%d\n",ans.size());
for(int i=ans.size()-1;i>=0;i--)
printf("%d%c",ans[i],i==0?'\n':' ');
}
return 0;
}