poj2923 (状态压缩01背包)

题意:
  两辆车去运一堆货物,货物数量小于等于10,问最少需要几趟能把货物全部运到目的地。
 1 #include <iostream>

 2 #include <cstdio>

 3 using namespace std;

 4 const int Ni = 1<<10;

 5 const int INF = 1<<27;

 6 int dp[Ni],g[Ni],weg[11];

 7 bool vis[Ni];

 8 int n,c1,c2,s;

 9 bool judge(int x)//可以一次用两辆车运走返回true

10 {

11     int i,j,sum=0;

12     for(i=0;i<=c1;i++) vis[i]=0;

13     vis[0]=1;

14     for(i=0;i<n;i++) if(x&(1<<i))

15     {

16         sum+=weg[i];

17         for(j=c1-weg[i];j>=0;j--)//j可以用c1一次运走j+weg[i]就可以一次运走

18             if(vis[j]) vis[j+weg[i]]=1;

19     }

20     for(i=c1;i>=0;i--)//x这个状态可以用两辆车一次运完return true

21         if(vis[i]&&sum-i<=c2) return true;

22     return false;

23 }

24 int main()

25 {

26     int i,j,t,cs=1;

27     cin>>t;

28     while(t--)

29     {

30         scanf("%d%d%d",&n,&c1,&c2);

31         for(i=0;i<n;i++) scanf("%d",weg+i);

32         if(c1>c2) swap(c1,c2);

33         for(s=0,i=1;i<1<<n;i++)//找出可以一次运走的所有状态

34             if(judge(i)) g[s++]=i;

35         for(i=(1<<n)-1;i>0;i--) dp[i]=INF;

36         dp[0]=0;

37         for(i=0;i<s;i++)

38             for(j=(1<<n)-1-g[i];j>=0;j--)//因为g[i]可以一次运走

39                 if(!(j&g[i])) dp[j|g[i]]=min(dp[j|g[i]],dp[j]+1);

40         printf("Scenario #%d:\n%d\n\n",cs++,dp[(1<<n)-1]);

41     }

42     return 0;

43 }

 

 



                            

你可能感兴趣的:(poj)