BZOJ2073 [POI2004]PRZ

本文探讨了一种集合状态转移方法,通过最小化时间优化集合s的状态转换,实现复杂问题的有效解决。利用预处理时间与空间优化,提高了算法效率。

自从知道"poi~"是什么意思以后。。。稳如poi~

一眼状压动规:

f[s]表示到集合s的时候,最少的时间

再定义time[s]表示集合s里的人一次通过桥的总时间,time[s] = max(t[i]) (i ∈ s)

sum[s]表示集合s里的人的总重量, sum[s] = Σ w[i] (i ∈ s)

f[s] = min(f[s1] + time[s2]) (sum[s2] ≤ W 且 s1 ∪ s2 = s, s1 ∩ s2 = ∅)

 

 1 /**************************************************************
 2     Problem: 2073
 3     User: rausen
 4     Language: C++
 5     Result: Accepted
 6     Time:340 ms
 7     Memory:1572 kb
 8 ****************************************************************/
 9  
10 #include <cstdio>
11 #include <cstring>
12 #include <algorithm>
13  
14 using namespace std;
15 const int N = 25;
16 const int M = 65536;
17  
18 int n, W;
19 int bin[N];
20 int t[N], w[N];
21 int f[M], time[M], sum_w[M];
22  
23 int main() {
24   int i, j;
25   scanf("%d%d", &W, &n);
26   for (i = bin[0] = 1; i < 20; ++i)
27     bin[i] = bin[i - 1] << 1;
28   for (i = 1; i <= n; ++i)
29     scanf("%d%d", t + i, w + i);
30   for (i = 1; i < bin[n]; ++i)
31     for (j = 1; j <= n; ++j)
32       if (i & bin[j - 1])
33     time[i] = max(time[i], t[j]), sum_w[i] += w[j];
34   memset(f, 127 / 3, sizeof(f));
35   f[0] = 0;
36   for (i = 1; i < bin[n]; ++i)
37     for (j = i; j; j = i & (j - 1))
38       if (sum_w[j] <= W)
39     f[i] = min(f[i], time[j] + f[i ^ j]);
40   printf("%d\n", f[bin[n] - 1]);
41   return 0;
42 }
View Code

 

转载于:https://www.cnblogs.com/rausen/p/4263790.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值