zoukankan      html  css  js  c++  java
  • Codeforces Round #436 (Div. 2) E. Fire

    http://codeforces.com/contest/864/problem/E

    题意:

    有一堆物品,每个物品有3个属性,需要的时间,失效的时间(一开始)和价值。只能一件一件的选择物品(即在选择这件物品时需要一定的时间,在这段时间之内不能选择其他物品),选择这件物品只能在失效时间之前选择。问选择的最大价值是多少。

    思路:

    对于每一个物品,有选和不选两种操作,与01背包是相似的。但是此题选择的顺序会影响到结果,这是01背包不同的地方。

    比如 a.st = 3,a.en = 5,a.v = 4

            b.st = 4,b.en = 8,b.v = 5

    这组数据先选择a,再选择b符合条件,价值最大,但是如果先选择b,那么a就没得选了,所以我们需要按照一定的顺序来选择。

    那么通过这个例子可以直观的感受到我们按结束时间排序之后进行选择得到的结果是最优的。

    背包的时候,把时间当作体积V,然后滚动数组优化时间就得逆序枚举,时间必须是失效时间-1(因为是在失效时间按之前),然巧妙的用一个vector来保存物品的编号就可以了。

    代码:

     1 #include <stdio.h>
     2 #include <vector>
     3 #include <algorithm>
     4 using namespace std;
     5 
     6 struct node
     7 {
     8     int s,e,v;
     9     int id;
    10 
    11     void read(void)
    12     {
    13         scanf("%d%d%d",&s,&e,&v);
    14     }
    15 } a[105];
    16 
    17 bool cmp(node aa,node bb)
    18 {
    19     return aa.e < bb.e;
    20 }
    21 
    22 int dp[2005];
    23 vector<int> g[2005];
    24 
    25 int main()
    26 {
    27     int n;
    28 
    29     scanf("%d",&n);
    30 
    31     for (int i = 1;i <= n;i++)
    32         a[i].read(),a[i].id = i;
    33 
    34     sort(a+1,a+n+1,cmp);
    35 
    36     for (int i = 1;i <= n;i++)
    37     {
    38         for (int j = a[i].e - 1;j >= a[i].s;j--)
    39         {
    40             if (dp[j] < dp[j-a[i].s] + a[i].v)
    41             {
    42                 dp[j] = dp[j-a[i].s] + a[i].v;
    43 
    44                 g[j].clear();
    45 
    46                 for (int k = 0;k < g[j-a[i].s].size();k++)
    47                     g[j].push_back(g[j-a[i].s][k]);
    48 
    49                 g[j].push_back(a[i].id);
    50             }
    51         }
    52     }
    53 
    54     int ans = 0,id = 0;
    55 
    56     for (int i = 1;i <= a[n].e;i++)
    57     {
    58         if (dp[i] > ans)
    59         {
    60             ans = dp[i];
    61             id = i;
    62         }
    63     }
    64 
    65     printf("%d
    ",ans);
    66     printf("%d
    ",g[id].size());
    67 
    68     for (int i = 0;i < g[id].size();i++)
    69     {
    70         if (!i) printf("%d",g[id][i]);
    71         else printf(" %d",g[id][i]);
    72     }
    73 
    74     return 0;
    75 }
  • 相关阅读:
    C++中的private/protected/public
    volatile关键字和mutable关键字
    vector容器使用和assert断言关键字
    静态变量static和extern外引用
    VS开发入门常识
    电子钱包的消费——java card开发第五篇
    电子钱包的圈存——java card开发第四篇
    PPT2010制作图片玻璃磨砂效果
    Word2010制作个人名片
    Word2010制作自动目录
  • 原文地址:https://www.cnblogs.com/kickit/p/7600021.html
Copyright © 2011-2022 走看看