码迷,mamicode.com
首页 > 其他好文 > 详细

codeforces 480D

时间:2014-10-29 18:58:46      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   os   ar   for   sp   div   

题意:给定一些物品放置在承重为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:

bubuko.com,布布扣
 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

 

codeforces 480D

标签:style   blog   http   color   os   ar   for   sp   div   

原文地址:http://www.cnblogs.com/yzcstc/p/4059899.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!