bzoj 2073 暴力

2073: [POI2004]PRZ

Time Limit: 10 Sec  Memory Limit: 64 MB
Submit: 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

Sample Output

42

HINT

Source

STAGE 2

 

这道题目的状态压缩暴力枚举转移的复杂度是∑(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 }

 

posted @ 2018-03-01 08:03  Kaiser-  阅读(129)  评论(0编辑  收藏  举报