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

BZOJ2621 [Usaco2012 Mar]Cows in a Skyscraper

时间:2015-05-01 22:30:27      阅读:230      评论:0      收藏:0      [点我收藏+]

标签:

首先比较容易想到是状态压缩DP

令$f[S]$表示选取了集合$S$以后,已经送了最少次数cnt且当前电梯剩下的体积rest最大(即$f[S]$是一个二元组(cnt, rest))

于是$f[S] = min_{i \in S} f[S - {i}] + v[i]$

$<$和$+$运算详情就请看程序好了,反正就是一个贪心思想,总复杂度$O(n * 2 ^ {n - 1})$

 

技术分享
 1 /**************************************************************
 2     Problem: 2621
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:532 ms
 7     Memory:13092 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <algorithm>
12  
13 using namespace std;
14 const int N = 20;
15 const int S = 1 << N;
16 const int inf = 1e9;
17  
18 int n, mx, mxs;
19 int a[S];
20  
21 struct data {
22     int cnt, rest;
23     data(int _c = 0, int _r = mx) : cnt(_c), rest(_r) {}
24      
25     inline data operator + (int t) const {
26         static data res;
27         res = *this;
28         res.rest -= t;
29         if (res.rest < 0) ++res.cnt, res.rest += mx;
30         return res;
31     }
32      
33     inline bool operator < (const data &d) const {
34         return cnt == d.cnt ? rest < d.rest : cnt < d.cnt;
35     }   
36 } f[S];
37  
38 int main() {
39     int i, s, t, now;
40     scanf("%d%d", &n, &mx);
41     mxs = (1 << n) - 1;
42     for (i = 1; i <= n; ++i) scanf("%d", &a[1 << i - 1]);
43     f[0] = data(0, mx);
44     for (s = 1; s <= mxs; ++s) {
45         t = s, f[s] = data(inf, mx);
46         while (t) {
47             now = t & (-t);
48             f[s] = min(f[s], f[s ^ now] + a[now]);
49             t -= now;
50         }
51     }
52     printf("%d\n", f[mxs].cnt + (f[mxs].rest != mx));
53     return 0;
54 }
55 
View Code

 

BZOJ2621 [Usaco2012 Mar]Cows in a Skyscraper

标签:

原文地址:http://www.cnblogs.com/rausen/p/4471198.html

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