• codeforces 480D


    题意:给定一些物品放置在承重为S的桌子上, 每个物品有5个属性,放置时间in,拿开时间out,重量w,承重s及放置后的收益v。而且后面放置上去的必须先拿开。。求一种合法的放置使得收益最大,输出收益。

    思路:先对所有的物品按照out递增,out相同l递减的情况排序。

           那么很容易想到dp。。

           f[i][j]表示放置了第i个,还可承重j的最大收益(i本身还没算)。

           把(in[i], out[i])看成线段

           那么,等价于(in[i], out[i])之间找出最多不相交线段。

           这个可以用记忆化搜索,当然也可以非递归。。

           具体看代码应该比较容易懂吧。。
    code:

     1 #include <bits/stdc++.h>
     2 using namespace std;
     3 struct oo{
     4     int l, r, w, s, v;
     5     void input(){
     6         scanf("%d%d%d%d%d", &l, &r, &w, &s, &v);
     7     }
     8     bool operator<(const oo& p) const{
     9         return r < p.r || (r == p.r && l > p.l);
    10     }
    11 } a[512];
    12 int n, s, f[512][1024], tmp[1024];
    13 void solve(){
    14     a[0] = (oo){0, n*2, 0, s, 0};
    15     for (int i = 1; i <= n; ++i) a[i].input();
    16     sort(a, a + n + 1);
    17     int cur, s1;
    18     for (int i = 0; i <= n; ++i)
    19         for (int j = a[i].w; j <= s; ++j){
    20              tmp[cur = a[i].l] = 0;
    21              s1 = min(j-a[i].w, a[i].s);
    22              for (int k = 0; k < i; ++k) if (a[k].l >= a[i].l){
    23                   for (;cur<a[k].r;)
    24                         ++cur, tmp[cur] = tmp[cur-1];
    25                   tmp[cur] = max(tmp[cur], tmp[a[k].l] + f[k][s1]);
    26              }
    27              f[i][j] = tmp[cur] + a[i].v;
    28         }
    29     cout << f[n][s] << endl;
    30 }
    31 
    32 int main(){
    33 //    freopen("a.in", "r", stdin);
    34     while (scanf("%d%d", &n, &s) != EOF){
    35          solve();
    36     } 
    37 }
    View Code
  • 相关阅读:
    学电脑入门与提高
    Autodesk Revit Architecture 2014官方标准教程
    Photoshop移动UI界面设计实用教程 全彩超值版
    中文版SQL Server 2000开发与管理应用实例
    Excel2016数据处理与分析从新手到高手
    云计算(第三版)
    无线局域网搭建与管理
    R语言数据挖掘
    Spring 3.0就这么简单
    SVN使用教程总结
  • 原文地址:https://www.cnblogs.com/yzcstc/p/4059899.html
Copyright © 2020-2023  润新知