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 }

时间: 2024-11-09 00:34:33

codeforces 480D的相关文章

Codeforces 480D Parcels(dp)

题目链接:Codeforces 480D Parcels 题目大意:就是有一个用来堆放货物的板,承重力为S.现在有N件货物,每件货物有到达的时间,运走的时间,以及 重量,承重,存放盈利.如果这件货物能再运达时间存放,并在指定时间取走的话,就能获得相应的盈利值.货物都是 逐个往上叠的,每个箱子上面的总重量不能大于箱子的承重.总的质量不能大于板的承重,货物上面还有货物的话是不 能被取走的.现在求最大的盈利值. 解题思路:dp好题,没想出来,看懂别人代码A掉的. 首先将货物按照运走时间早的,运进时间晚

【codeforces 718E】E. Matvey&#39;s Birthday

题目大意&链接: http://codeforces.com/problemset/problem/718/E 给一个长为n(n<=100 000)的只包含‘a’~‘h’8个字符的字符串s.两个位置i,j(i!=j)存在一条边,当且仅当|i-j|==1或s[i]==s[j].求这个无向图的直径,以及直径数量. 题解:  命题1:任意位置之间距离不会大于15. 证明:对于任意两个位置i,j之间,其所经过每种字符不会超过2个(因为相同字符会连边),所以i,j经过节点至多为16,也就意味着边数至多

Codeforces 124A - The number of positions

题目链接:http://codeforces.com/problemset/problem/124/A Petr stands in line of n people, but he doesn't know exactly which position he occupies. He can say that there are no less than a people standing in front of him and no more than b people standing b

Codeforces 841D Leha and another game about graph - 差分

Leha plays a computer game, where is on each level is given a connected graph with n vertices and m edges. Graph can contain multiple edges, but can not contain self loops. Each vertex has an integer di, which can be equal to 0, 1 or  - 1. To pass th

Codeforces Round #286 (Div. 1) A. Mr. Kitayuta, the Treasure Hunter DP

链接: http://codeforces.com/problemset/problem/506/A 题意: 给出30000个岛,有n个宝石分布在上面,第一步到d位置,每次走的距离与上一步的差距不大于1,问走完一路最多捡到多少块宝石. 题解: 容易想到DP,dp[i][j]表示到达 i 处,现在步长为 j 时最多收集到的财富,转移也不难,cnt[i]表示 i 处的财富. dp[i+step-1] = max(dp[i+step-1],dp[i][j]+cnt[i+step+1]) dp[i+st

Codeforces 772A Voltage Keepsake - 二分答案

You have n devices that you want to use simultaneously. The i-th device uses ai units of power per second. This usage is continuous. That is, in λ seconds, the device will use λ·ai units of power. The i-th device currently has bi units of power store

Educational Codeforces Round 21 G. Anthem of Berland(dp+kmp)

题目链接:Educational Codeforces Round 21 G. Anthem of Berland 题意: 给你两个字符串,第一个字符串包含问号,问号可以变成任意字符串. 问你第一个字符串最多包含多少个第二个字符串. 题解: 考虑dp[i][j],表示当前考虑到第一个串的第i位,已经匹配到第二个字符串的第j位. 这样的话复杂度为26*n*m*O(fail). fail可以用kmp进行预处理,将26个字母全部处理出来,这样复杂度就变成了26*n*m. 状态转移看代码(就是一个kmp

Codeforces Round #408 (Div. 2) B

Description Zane the wizard is going to perform a magic show shuffling the cups. There are n cups, numbered from 1 to n, placed along the x-axis on a table that has m holes on it. More precisely, cup i is on the table at the position x?=?i. The probl

Codeforces 617 E. XOR and Favorite Number

题目链接:http://codeforces.com/problemset/problem/617/E 一看这种区间查询的题目,考虑一下莫队. 如何${O(1)}$的修改和查询呢? 令${f(i,j)}$表示区间${\left [ l,r \right ]}$内数字的异或和. 那么:${f(l,r)=f(1,r)~~xor~~f(1,l-1)=k}$ 记一下前缀异或和即可维护. 1 #include<iostream> 2 #include<cstdio> 3 #include&l