zoukankan      html  css  js  c++  java
  • poj 2923 状压dp+01背包

    好牛b的思路

    题意:一系列物品,用二辆车运送,求运送完所需的最小次数,两辆车必须一起走

    解法为状态压缩DP+背包,
    本题的解题思路是先枚举选择若干个时的状态,
    总状态量为1<<n,判断这些状态集合里的那些物品能否一次就
    运走,如果能运走,那就把这个状态看成一个物品。预处理完能
    从枚举中找到tot个物品,再用这tol个物品中没有交集
    (也就是两个状态不能同时含有一个物品)的物品进
    行01背包,每个物品的体积是state[i],价值是1,求
    包含n个物品的最少价值也就是dp[(1<<n)-1](dp[i]表示状态i需要运的最少次数)。

    状态转移方程:dp[j|k] = min(dp[j|k],dp[k]+1) (k为state[i,1<=j<=(1<<n)-1])。
    算法复杂度O((2^N)*N)

     1 #include<stdio.h>
     2 #include<iostream>
     3 #include<string.h>
     4 #include<algorithm>
     5 #include<math.h>
     6 using namespace std;
     7 const int INF=0x3f3f3f3f;
     8 int state[1030];
     9 int tol;
    10 int dp[1030];
    11 int n,C1,C2;
    12 int cost[110];
    13 bool vis[1030];
    14 
    15 bool judge(int x)
    16 {
    17     int sum=0;
    18     memset(vis,false,sizeof(vis));
    19     vis[0]=true;
    20     for(int i=0;i<n;i++)
    21     {
    22         if((1<<i)&x)
    23         {
    24             sum+=cost[i];
    25             for(int j=C1;j>=cost[i];j--)
    26               if(vis[j-cost[i]])
    27                  vis[j]=true;
    28         }
    29     }
    30     if(sum>C1+C2)return false;
    31     for(int i=0;i<=C1;i++)
    32       if(vis[i]&&sum-i<=C2)
    33         return true;
    34     return false;
    35 }
    36 int main()
    37 {
    38     int T;
    39     int iCase=0;
    40     scanf("%d",&T);
    41     while(T--)
    42     {
    43         iCase++;
    44         scanf("%d%d%d",&n,&C1,&C2);
    45         for(int i=0;i<n;i++)
    46           scanf("%d",&cost[i]);
    47         for(int i=0;i<(1<<n);i++)dp[i]=INF;
    48         dp[0]=0;
    49         tol=0;
    50         for(int i=1;i<(1<<n);i++)
    51           if(judge(i))
    52             state[tol++]=i;
    53         for(int i=0;i<tol;i++)
    54           for(int j=(1<<n)-1;j>=0;j--)
    55           {
    56               if(dp[j]==INF)continue;
    57               if((j&state[i])==0)
    58               {
    59                   dp[j|state[i]]=min(dp[j|state[i]],dp[j]+1);
    60               }
    61           }
    62         printf("Scenario #%d:
    %d
    
    ",iCase,dp[(1<<n)-1]);
    63     }
    64     return 0;
    65 }
  • 相关阅读:
    Vue的条件渲染详解
    Vue的style绑定
    Vue的class绑定总结
    v-model详解
    MUI手势锁
    mysql主从搭建
    处理绿盟科技安全评估的系统漏洞
    微信小程序发送ajax
    微信小程序上拉下拉刷新
    微信小程序覆盖自定义组件样式
  • 原文地址:https://www.cnblogs.com/cnblogs321114287/p/4351985.html
Copyright © 2011-2022 走看看