zoukankan      html  css  js  c++  java
  • Come to a spring outing BNU 29358

    http://www.bnuoj.com/bnuoj/problem_show.php?pid=29358

    这个题目的话,初看就想到要用背包,一个包一个包的装,装好两个包的话,就可以直接判断了。

    当然中间还有剪枝的部分,代码中有很好的体现,这个怎么说呢,代码写了很多,但是是为了节省时间,比较划来的。

    当然这个问题最重要的不是剪枝,而是背包算法的运用:如何标记第一个背包已经使用过的物品。

    为了标记,我觉得使用二维dp数组比一维数组好,但是标记后的处理也十分重要,详见代码。

    此处本人还耍了一点小聪明,标记的话,第二次读的时候n和整个数组都变了,突发奇想,把标记了的物品体积赋值为0.这样就不会影响其它的背包了。

    代码如下:

      1 #include<cstdio>
      2 #include<cstring>
      3 #include<algorithm>
      4 using namespace std;
      5 #define M 450
      6 #define mem0(f) memset(f,0,sizeof(f))
      7 int t;
      8 int n,c;
      9 int v[M];
     10 int dp[M][M];//二维背包数组
     11 int vis[M][M];//表示第i个物品在构成j时是否被选用
     12 int s;
     13 int ok;
     14 int biaoji[M];
     15 int main()
     16 {
     17     scanf("%d",&t);
     18     for(int tt=1;tt<=t;tt++)
     19     {
     20         ok=1;
     21         scanf("%d%d",&n,&c);
     22         s=0;
     23         mem0(v);
     24 
     25         for(int i=1;i<=n;i++)//用二维数组的话,一定要从1开始存入
     26         {
     27             scanf("%d",&v[i]);
     28             if(v[i]>c)
     29             {
     30                 ok=0;
     31             }
     32             s+=v[i];
     33         }
     34         if(s>3*c)ok=0;
     35         if(ok==0)
     36         {
     37             printf("Case %d: No
    ",tt);
     38             continue;
     39         }
     40         int p=2;
     41        // mem0(dp);
     42        mem0(biaoji);
     43         while(p--)
     44         {
     45         mem0(vis);
     46         mem0(dp);
     47         for(int i=1;i<=n;i++)
     48         {
     49             //if(biaoji[i])continue;
     50             for(int k=c;k>=0;k--)
     51             {
     52                 //
     53                 if(k>=v[i])
     54                 {
     55                 if(dp[i-1][k]>dp[i-1][k-v[i]]+v[i])
     56                 {
     57                     dp[i][k]=dp[i-1][k];
     58                     vis[i][k]=0;
     59                 }
     60                 else
     61                 {
     62                     dp[i][k]=dp[i-1][k-v[i]]+v[i];
     63                     vis[i][k]=1;
     64                 }
     65                 }
     66                 else
     67                 {
     68                     dp[i][k]=dp[i-1][k];
     69                     vis[i][k]=0;
     70                 }
     71             }
     72         }
     73        // printf("tttttttttt%d
    ",dp[n][c]);
     74         //第一个背包
     75 
     76         if(p==1&&dp[n][c]<(double)s/3)//剪枝
     77         {
     78             printf("Case %d: No
    ",tt);
     79             break;
     80         }
     81         s-=dp[n][c];
     82         if(p==0&&dp[n][c]<(double)s/2)//剪枝
     83         {
     84             printf("Case %d: No
    ",tt);
     85             break;
     86         }
     87 
     88         if(p==0)
     89         {
     90             s<=c;
     91             printf("Case %d: Yes
    ",tt);
     92             break;
     93         }
     94         if(s<=0)
     95         {
     96             printf("Case %d: Yes
    ",tt);
     97             break;
     98         }
     99         int pt=0,vv=c;
    100         for(int i=n;i>=1;i--)
    101         {
    102             if(!vis[i][vv])
    103             {
    104                 biaoji[i]=0;
    105                 //v[i]=0;
    106             }
    107                 else
    108             {
    109                 biaoji[i]=1;vv=vv-v[i];
    110                 v[i]=0;//把装过了的值赋为0
    111             }
    112 
    113         }
    114         }
    115     }
    116     return 0;
    117 }
  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/plank-george-zzo/p/3280078.html
Copyright © 2011-2022 走看看