题意:
房间着火了,里面有n件物品,每件物品有营救需要的时间t,被烧坏的最晚时间d,他的价值p,问能得到的最大价值,并且输出营救出来的物品编号
代码:
//必然是先救存活时间短的即d小的,所以先排个序,dp[i][j]表示枚举到第i件物品时救出他的时间是j时的最大价值,然后就 //是取还是不取这件物品的问题了他的状态是由dp[i-1][~]转移来的。另外这题需要记录取了哪些物品,用g[i][j]表示第i件 //物品在j时间取没取,用pre数组记录前驱。输出还要按照取得顺序输出。 #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int INF=0x7fffffff; int f[109][2009],g[109][2009],pre[109][2009][2]; struct Lu { int t,d,p,id; bool operator < (const Lu &x)const{ return d<x.d; } }L[109]; int main() { int n; scanf("%d",&n); for(int i=1;i<=n;i++){ scanf("%d%d%d",&L[i].t,&L[i].d,&L[i].p); L[i].id=i; } sort(L+1,L+1+n); memset(g,0,sizeof(g)); memset(pre,0,sizeof(pre)); for(int i=1;i<=n;i++){ for(int j=1;j<=2000;j++){ f[i][j]=f[i-1][j]; pre[i][j][0]=i-1; pre[i][j][1]=j; if(j>=L[i].t&&j<L[i].d){ if(L[i].p+f[i-1][j-L[i].t]>f[i][j]){ f[i][j]=L[i].p+f[i-1][j-L[i].t]; g[i][j]=1; pre[i][j][0]=i-1; pre[i][j][1]=j-L[i].t; } } } } int ans1=-INF,ans2=0; for(int i=1;i<=2000;i++){ if(f[n][i]>ans1){ ans1=f[n][i]; ans2=i; } } printf("%d ",ans1); int q[2009],l=0,i=n,j=ans2; while(i!=0){ if(g[i][j]) q[++l]=L[i].id; int tmp1=pre[i][j][0]; int tmp2=pre[i][j][1]; i=tmp1;j=tmp2; } printf("%d ",l); for(int i=l;i>=1;i--) printf("%d%c",q[i],i==1?' ':' '); return 0; }