Bzoj 2073 [POI2004]PRZ

2073: [POI2004]PRZ

Time Limit: 10 Sec  Memory Limit: 64 MB

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
solution:
    dp的题,但本菜鸟表示不会转移,于是打了dfs。。。
 1 #pragma GCC optimize("O3")
 2 #include <iostream>
 3 #include <cstdio>
 4 #include <cstring>
 5 #include <algorithm>
 6 using namespace std;
 7 #define N 100005
 8 #define M 500005
 9 int read() {
10     int s=0,f=1;
11     char ch=getchar();
12     for( ; ch<'0'||ch>'9'; f=(ch=='-')?-1:f,ch=getchar()) ;
13     for( ; ch>='0'&&ch<='9'; s=s*10+(ch^48),ch=getchar()) ;
14     return s*f;
15 }
16 int ans=0x5f5f5f5f,bit[120],mx,w,n,Time[30],weight[30],sum[1<<17|1],T[1<<17|1],state[1<<17|1],cnt,tmp[1<<17|1];
17 void init() {
18     memset(tmp,0x5f,sizeof(tmp));
19     for(int i=1; i<=20; ++i) bit[i]=(1<<(i-1));
20     for(int i=0; i<=mx; ++i) {
21         for(int j=1; j<=n; ++j) if(i&bit[j]) T[i]=max(T[i],Time[j]);
22         if(sum[i]<=w&&i) state[++cnt]=i;    
23         for(int j=1; j<=n; ++j) if(!(i&bit[j])) sum[i|bit[j]]=sum[i]+weight[j];
24     } 
25 }
26 void dfs(int Sta,int now) {
27     if(Sta==mx) {ans=min(now,ans); return ;}
28     if(now>=ans) return ;
29     if(now>=tmp[Sta]) return ;
30     tmp[Sta]=now;
31     for(int i=cnt; i; --i) if(!(Sta&state[i])) dfs(Sta|state[i],now+T[state[i]]);
32 }
33 int main() {
34     w=read(),n=read();mx=(1<<n)-1;
35     for(int i=1; i<=n; ++i) Time[i]=read(),weight[i]=read();
36     init(); dfs(0,0);
37     printf("%d",ans);
38     return 0;
39 }

 

 
posted @ 2017-10-26 21:16  Forever_goodboy  阅读(243)  评论(0编辑  收藏  举报