URAL1326. Bottle Taps(状压)

1326

用队列优化的 不知道为什么一直WA  传统直白的 状压 写了超时 O((1<<n)*m*n) 之后想了可以把n省去 预处理一下方案

 1 #include <iostream>

 2 #include<cstdio>

 3 #include<cstring>

 4 #include<algorithm>

 5 #include<stdlib.h>

 6 #include<vector>

 7 #include<cmath>

 8 using namespace std;

 9 #define N 1100000

10 #define INF 0xfffffff

11 int dp[2][N];

12 int p[25],o[110],sum[110];

13 vector<int>a[110];

14 bool f[2][N],ff[25];

15 int main()

16 {

17     int i,j,n,m,v,s=0;

18     cin>>n;

19     for(i = 1; i <= n ; i++)

20     cin>>p[i];

21     cin>>m;

22     for(i = 1; i <= m ;i++)

23     {

24         int k,b;

25         cin>>o[i]>>k;

26         for(j = 1; j <= k ; j++)

27         {

28             cin>>b;

29             sum[i]+=(1<<(b-1));

30         }

31     }

32     cin>>v;

33     for(i = 1; i <= v ; i++)

34     {

35         int x;

36         cin>>x;

37         ff[x] = 1;

38         s+=(1<<(x-1));

39     }

40     int tt[2]={0};

41     tt[0]=1;

42     for(i =0  ;i < (1<<n) ; i++)

43     dp[0][i] = dp[1][i] = INF;

44     for(i = 0; i < (1<<n)  ; i++)

45     {

46         int pp=0,flag=1;

47         for(j = 0 ; j < n ; j++)

48         {

49             if(i&(1<<j))

50             {

51                 if(!ff[j+1]) flag=0;

52                 pp+=p[j+1];

53             }

54         }

55         if(!flag) continue;

56         dp[0][i] = pp;

57     }

58     for(i = 1; i <= m ;i++)

59     {

60         int t1 = i%2,t2 = (i-1)%2;

61         for(j = 0 ; j < (1<<n) ; j++)

62         {

63             dp[t1][j] = min(dp[t1][j],dp[t2][j]);

64             if(dp[t2][j]==INF) continue;

65             dp[t1][j|sum[i]] = min(dp[t1][j|sum[i]],dp[t2][j]+o[i]);

66         }

67     }

68     int minz = INF;

69     for(i = 0 ; i < (1<<n) ; i++)

70     {

71         if((s&i)==s)

72         {

73             minz = min(minz,min(dp[0][i],dp[1][i]));

74         }

75     }

76     cout<<minz<<endl;

77     return 0;

78 }
View Code

 

你可能感兴趣的:(PS)