hdu 4381(背包问题)

题意:有一排箱子全是黑色的,然后有两种操作1 a x从1-a跳出x个变成白色。2 a x从a-x跳出x个变成白色。要你求最多能变成白色的个数和最少的操作数。

思路:转化成背包问题,把两种操作分开进行背包,最后两重循环枚举找最优解即可。

代码如下:

  1 /**************************************************
  2  * Author     : xiaohao Z
  3  * Blog     : http://www.cnblogs.com/shu-xiaohao/
  4  * Last modified : 2014-03-29 15:45
  5  * Filename     : MulSchool.cpp
  6  * Description     : 
  7  * ************************************************/
  8 
  9 #include <iostream>
 10 #include <cstdio>
 11 #include <cstring>
 12 #include <cstdlib>
 13 #include <cmath>
 14 #include <algorithm>
 15 #include <queue>
 16 #include <stack>
 17 #include <vector>
 18 #include <set>
 19 #include <map>
 20 #define MP(a, b) make_pair(a, b)
 21 #define PB(a) push_back(a)
 22 
 23 using namespace std;
 24 typedef long long ll;
 25 typedef pair<int, int> pii;
 26 typedef pair<unsigned int,unsigned int> puu;
 27 typedef pair<int, double> pid;
 28 typedef pair<ll, int> pli;
 29 typedef pair<int, ll> pil;
 30 
 31 const int INF = 0x3f3f3f3f;
 32 const double eps = 1E-6;
 33 const int LEN = 100000+10;
 34 int T, n, m, ta, tb, dp1[LEN], dp2[LEN];
 35 struct OP{
 36     int pos, x;
 37 };
 38 OP op1[LEN], op2[LEN];
 39 
 40 bool cmp1(OP a, OP b){
 41     if(a.pos != b.pos) return a.pos < b.pos;
 42     else a.x < b.x;
 43 }
 44 
 45 bool cmp2(OP a, OP b){
 46     if(a.pos != b.pos) return a.pos > b.pos;
 47     else a.x < b.x;
 48 }
 49 
 50 int main()
 51 {
 52 //    freopen("in.txt", "r", stdin);
 53 
 54     int kase = 1;
 55     scanf("%d", &T);
 56     while(T--){
 57         scanf("%d%d", &n, &m);
 58         ta = tb = 0;
 59         memset(dp1, 0x3f, sizeof dp1);
 60         memset(dp2, 0x3f, sizeof dp2);
 61         for(int i=0; i<m; i++){
 62             int op = 0, a, b;
 63             scanf("%d%d%d", &op, &a, &b);
 64             if(op == 1) {
 65                 op1[ta].pos = a;
 66                 op1[ta].x = b;
 67                 ta++;
 68             }else{
 69                 op2[tb].pos = a;
 70                 op2[tb].x = b;
 71                 tb++;
 72             }
 73         }
 74         sort(op1, op1+ta, cmp1);
 75         sort(op2, op2+tb, cmp2);
 76         dp1[0] = dp2[n+1] = 0;
 77         for(int j=0; j<ta; j++){
 78             for(int i=n; i>=0; i--){
 79                 if(op1[j].pos >= i && i - op1[j].x >= 0 && dp1[i - op1[j].x] != INF){
 80                     dp1[i] = min(dp1[i], dp1[i - op1[j].x]+1);
 81                 }
 82             }
 83         }
 84         for(int j=0; j<tb; j++){
 85             for(int i=1; i<=n+1; i++){
 86                 if(op2[j].pos <= i && i + op2[j].x <= n+1 && dp2[i + op2[j].x] != INF){
 87                     dp2[i] = min(dp2[i], dp2[i + op2[j].x]+1);
 88                 }     
 89             }
 90         }
 91         int ansa = INF, ansb = INF;
 92         for(int i=0; i<=n; i++){
 93             for(int j=i+1; j<=n+1; j++){
 94                 if(dp1[i] != INF && dp2[j] != INF){
 95                     if(j-i-1 < ansa){
 96                         ansa = j-i-1;
 97                         ansb = dp1[i] + dp2[j];
 98                     }
 99                     if(j-i-1 == ansa){
100                         ansb = min(dp1[i] + dp2[j], ansb);
101                     }
102                 }
103             }
104         }
105         if(ansb == INF) ansb = 0;
106         printf("Case %d: %d %d\n", kase++, n-ansa, ansb);
107     }
108     return 0;
109 }
View Code

 

posted @ 2014-03-29 19:23  张小豪  阅读(229)  评论(0编辑  收藏  举报