Codeforces 864E - Fire(dp)

原题连接:http://codeforces.com/problemset/problem/864/E

 

题意:一个人想从大火中带走一些东西。每次他只能带一个,耗时ti ,价值为pi, 当总时间超过di时不能被带走。问他如何按顺序带走物品使价值总和最大。

思路:背包问题。分为取和不取两种情况1.dp[i][j]=max(dp[i-1][j], dp[i-1][j-t]+p), j<d;

                  2.dp[i][j]=max(dp[i-1][j], dp[i][j]);

 

AC代码:

 

 1 #include<iostream>
 2 #include<cstring>
 3 #include<cstdio>
 4 #include<algorithm>
 5 #include<vector>
 6 using namespace std;
 7 struct G{
 8     int t,d,v;
 9     int id;
10 }g[105];
11 int dp[105][2005];
12 bool vis[105][2005];
13 bool cmp(G a, G b){
14     return a.d<b.d;
15 }
16 int main()
17 {
18     int n,maxx=0;
19     scanf("%d", &n);
20     memset(dp, 0, sizeof(dp));
21     memset(vis, 0, sizeof(vis));
22     for(int i=1;i<=n;i++){
23         scanf("%d %d %d", &g[i].t, &g[i].d, &g[i].v);
24         g[i].id=i;
25         maxx=max(maxx, g[i].d);
26     } 
27     sort(g+1, g+n+1, cmp);
28     int b;
29     for(int i=1;i<=n;i++){
30         b=0;
31         for(int j=0;j<=maxx;j++){
32             if(j>=g[i].t&&j<g[i].d&&dp[i-1][j]<dp[i-1][j-g[i].t]+g[i].v){
33                 dp[i][j]=dp[i-1][j-g[i].t]+g[i].v;                    
34                 vis[i][j]=1;
35             }
36             else dp[i][j]=dp[i-1][j];
37             if(dp[i][j]>=dp[i][b]) b=j;
38         }
39     }
40     printf("%d\n", dp[n][b]);
41     vector<int> ans;
42     for(int i=n;i;i--){//反推,得到最优取法
43         if(vis[i][b]){
44             ans.push_back(g[i].id);
45             b-=g[i].t;
46         }
47     }
48     printf("%d\n", ans.size());
49     for(int i=ans.size()-1;i>=0;i--) printf("%d ",ans[i]);
50     return 0;
51 }

 

posted @ 2017-09-28 00:46  Bangbangbanana  阅读(397)  评论(0编辑  收藏  举报