自从知道"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 ", f[bin[n] - 1]); 41 return 0; 42 }