bzoj 2073 暴力
2073: [POI2004]PRZ
Time Limit: 10 Sec Memory Limit: 64 MBSubmit: 442 Solved: 327
[Submit][Status][Discuss]
Description
一只队伍在爬山时碰到了雪崩,他们在逃跑时遇到了一座桥,他们要尽快的过桥. 桥已经很旧了, 所以它不能承受太重的东西. 任何时候队伍在桥上的人都不能超过一定的限制. 所以这只队伍过桥时只能分批过,当一组全部过去时,下一组才能接着过.
队伍里每个人过桥都需要特定的时间,当一批队员过桥时时间应该算走得最慢的那一个,每个人也有特定的重量,我们想知道如何分批过桥能使总时间最少.
Input
第一行两个数: w – 桥能承受的最大重量(100 <=
w <= 400) 和 n – 队员总数(1 <= n <= 16). 接下来n 行每行两个数分别表示: t –
该队员过桥所需时间(1 <= t <= 50) 和 w – 该队员的重量(10 <= w <= 100).
Output
输出一个数表示最少的过桥时间.
Sample Input
100 3
24 60
10 40
18 50
24 60
10 40
18 50
Sample Output
42
HINT
Source
这道题目的状态压缩暴力枚举转移的复杂度是∑(Cn,i * 2^i)渐进与3^n
这个我不知道,考试是打表找复杂度吧。
1 #pragma GCC optimize(2) 2 #pragma G++ optimize(2) 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 #include<cstdio> 7 #include<cstring> 8 9 #define N 70007 10 #define inf 1000000007 11 using namespace std; 12 inline int read() 13 { 14 int x=0,f=1;char ch=getchar(); 15 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 16 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 17 return x*f; 18 } 19 20 int w,n; 21 int weight[N],tim[N],f[N]; 22 struct Node 23 { 24 int t,w; 25 }a[18]; 26 27 void dfs(int dep,int now,int slow,int zl) 28 { 29 if(dep==n) 30 { 31 weight[now]=zl; 32 tim[now]=slow; 33 return; 34 } 35 dep++; 36 dfs(dep,now<<1|1,max(slow,a[dep].t),zl+a[dep].w); 37 dfs(dep,now<<1,slow,zl); 38 } 39 int main() 40 { 41 w=read(),n=read(); 42 for (int i=1;i<=n;i++)a[i].t=read(),a[i].w=read(); 43 dfs(0,0,0,0); 44 f[0]=0;int up=1<<n; 45 for (int i=1;i<up;i++)f[i]=inf; 46 for (int i=1;i<up;i++) 47 { 48 for (int j=i;j;j=(j-1)&i) 49 if(weight[j]<=w) f[i]=min(f[i],f[i^j]+tim[j]); 50 } 51 printf("%d\n",f[up-1]); 52 }