首页 > 代码库 > poj 2923 Relocation 解题报告

poj 2923 Relocation 解题报告

题目链接:http://poj.org/problem?id=2923

题目意思:给出两部卡车能装的最大容量,还有n件物品的分别的weight。问以最优方式装入,最少能运送的次数是多少。

  

     二进制表示物品状态:0表示没运走,1表示已被运走。

  枚举出两辆车一趟可以运出的状态。由于物品是一趟一趟运出来的。所以就可以由一个状态通过两辆车一趟的状态转移到另一个状态。

  dp[i]=MIN(dp[k]+1)。k可以由两车一趟转移到i。

      我是参考此人的:http://blog.csdn.net/bossup/article/details/9363845

      状态压缩DP啊啊啊啊~~~~真神奇!!!!

     

 1 #include <iostream> 2 #include <cstdio> 3 #include <cstdlib> 4 #include <cstring> 5 using namespace std; 6  7 const int INF = 1e9; 8 const int maxn = 100 + 5; 9 int w[maxn];10 int c1, c2, cnt, n;11 int dp[1<<10], state[1<<10];   12 // dp[i]:状态为i时需要的最少趟数13 // state[i]:两辆车一趟可以运的合理状态14 15 void dfs(int num, int c1, int c2, int s)  // s:每一次决策完的状态16 {17     if (num >= n)  // n件物品全部决策完18     {19         if (!dp[s])  // 这个状态之前没试过20         {21             dp[s] = 1;22             state[cnt++] = s;  23         }24         return;25     }26     if (c1 >= w[num])27         dfs(num+1, c1-w[num], c2, s|(1<<num));  // 尝试装去第一部车上   28     if (c2 >= w[num])29         dfs(num+1, c1, c2-w[num], s|(1<<num));  // 尝试装去第二部车上30     dfs(num+1, c1, c2, s);  // 两车都不装31 }32 33 int main()34 {35     int T, cas = 0;36     while (scanf("%d", &T) != EOF)37     {38         while (T--)39         {40             scanf("%d%d%d", &n, &c1, &c2);41             for (int i = 0; i < n; i++)42                 scanf("%d", &w[i]);43             memset(dp, 0, sizeof(dp));44             cnt = 0;45             dfs(0, c1, c2, 0);46             for (int i = 0; i <= (1<<n)-1; i++)47                 dp[i] = (i == 0 ? 0 : INF);48     //        memset(dp, 0x3f, sizeof(dp));49     //        dp[0] = 0;50     //        printf("cnt = %d\n", cnt);51             for (int i = 0; i < (1<<n); i++)  // 枚举状态数52             {53                 for (int j = 0; j < cnt; j++)54                 {55                     if (i & state[j])   // 同一件物品被选了两次,有冲突(真厉害的操作啊~)56                         continue;57                     int newstate = i | state[j];  // 新的一个状态58                     dp[newstate] = min(dp[newstate], dp[i]+1);59                 }60             }61             printf("Scenario #%d:\n%d\n", ++cas, dp[(1<<n)-1]);62             if (T)63                 puts("");64         }65     }66     return 0;67 }