首页 > 代码库 > [luoguP3052] [USACO12MAR]摩天大楼里的奶牛Cows in a Skyscraper(DP)

[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

 

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