[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

 

转载于:https://www.cnblogs.com/zhenghaotian/p/6910275.html

08-27
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值