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 }