[luoguP3052] [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper(DP)

传送门

 

输出被阉割了。

只输出最少分的组数即可。

f 数组为结构体

f[S].cnt 表示集合 S 最少的分组数

f[S].v  表示集合 S 最少分组数下当前组所用的最少容量

f[S] = min(f[S], f[S - i] + a[i]) (i ∈ S)

运算重载一下即可。

 

——代码

 1 #include <cstdio>
 2 #include <iostream>
 3 
 4 int n, m, w;
 5 int a[19];
 6 struct qwq
 7 {
 8     int cnt, v;
 9     qwq(int cnt = 0, int v = 0) : cnt(cnt), v(v) {}
10 }f[1 << 19];
11 
12 inline qwq operator + (const qwq x, const int d)
13 {
14     return x.v + d <= w ? qwq(x.cnt, x.v + d) : qwq(x.cnt + 1, d);
15 }
16 
17 inline bool operator < (const qwq x, const qwq y)
18 {
19     return x.cnt == y.cnt ? x.v < y.v : x.cnt < y.cnt;
20 }
21 
22 inline qwq min(qwq x, qwq y)
23 {
24     return x < y ? x : y;
25 }
26 
27 inline int read()
28 {
29     int x = 0, f = 1;
30     char ch = getchar();
31     for(; !isdigit(ch); ch = getchar()) if(ch == '-') f = -1;
32     for(; isdigit(ch); ch = getchar()) x = (x << 1) + (x << 3) + ch - '0';
33     return x * f;
34 }
35 
36 int main()
37 {
38     int i, S;
39     n = read();
40     w = read();
41     m = (1 << n) - 1;
42     for(i = 1; i <= n; i++) a[i] = read();
43     for(S = 1; S <= m; S++)
44     {
45         f[S] = qwq(1e9, w);
46         for(i = 1; i <= n; i++)
47         {
48             if(!((1 << i - 1) & S)) continue;
49             f[S] = min(f[S], f[(1 << i - 1) ^ S] + a[i]);
50         }
51     }
52     printf("%d\n", f[m].cnt + 1);
53     return 0;
54 }
View Code

 

posted @ 2017-05-26 20:09  zht467  阅读(148)  评论(0编辑  收藏  举报