Codeforces Round #436 (Div. 2) E. Fire

题意:给你n个需要救得东西,每个东西给出t,d,p,表示需要花费t时间,在d时间之前,价值为p,问救出最多价值,并把每个东西序号输出,比如  3  3  4 ,这就无法救出

思路:dp,dp[i][j]表示救出第i个花费j时间救出最大价值,dp[i][j]=max(dp[i][j],dp[i-1][j-a[i][d]]+a[i].val)(j<=2000),再记录个g[i][j]表示第i个东西在j时间是救出来的,然后倒推

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int N=110;
 5 
 6 int dp[N][4002];
 7 int g[N][4002];
 8 struct node{
 9     int t,d,val,id;
10 }a[N];
11 int n;
12 
13 bool cmp(node p,node q){
14     return p.d<q.d;
15 }
16 
17 void slove(int x,int y,int s){
18 
19     if(x==0){
20         cout<<s<<endl;return ;
21     }
22     else {
23         if(!g[x][y]){
24             slove(x-1,y,s);
25         }
26         else {
27 
28             slove(x-1,y-a[x].t,s+1);
29 
30             cout<<a[x].id<<" ";
31         }
32     }
33 }
34 int main(){
35     scanf("%d",&n);
36     for(int i=1;i<=n;i++){
37         scanf("%d%d%d",&a[i].t,&a[i].d,&a[i].val);
38         a[i].id=i;
39     }
40     sort(a+1,a+1+n,cmp);
41     for(int i=1;i<=n;i++){
42         for(int j=0;j<=2000;j++){
43             dp[i][j]=dp[i-1][j];
44             g[i][j]=0;
45             if(a[i].t<=j&&a[i].d>j){
46                 if(dp[i-1][j-a[i].t]+a[i].val>dp[i][j]){
47                     g[i][j]=1;
48                     dp[i][j]=dp[i-1][j-a[i].t]+a[i].val;
49                 }
50             }
51         }
52     }
53     int Max=0;
54     int xx=0,yy=0;
55     for(int i=1;i<=n;i++)
56         for(int j=1;j<=2001;j++){
57             if(Max<dp[i][j]){
58                 xx=i;yy=j;
59                 Max=dp[i][j];
60             }
61         }
62    // cout<<xx<<" "<<yy<<" "<<g[xx][yy]<<endl;
63     cout<<Max<<endl;
64     slove(xx,yy,0);
65 }
原文地址:https://www.cnblogs.com/hhxj/p/7596093.html