zoj3703:

题意:给定一个背包的空间和物品个数,求出这个背包装的价值最大且物品个数最多的方案的价值,物品个数,解题时间(比赛计时那样算)

解题思路:裸0-1背包加记录路径,不过还要加上一个条件限制 :到达同一状态的物品总数尽可能大 ,所以要开一个辅助数组来记录某一状态的取物品个数

解题代码:

View Code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int f[55][1005];
int g[55][1005];
int p[55][1005];
int c[55];
int w[55];
int k[55];
int tsum[55];

int MAX(int x, int y )
{
    return x > y? x:y;
}
int cmp(const void *a, const void *b)
{
     return *(int*)a -*(int *)b;
}

int main()
{
    int t ;
    scanf("%d",&t);
    while(t--)
    { 
      memset(f,0,sizeof(f));
      memset(g,0,sizeof(g));
      memset(k,0,sizeof(k));
      memset(p,0,sizeof(p));
      memset(tsum,0,sizeof(tsum));
      int v, n;
      
      scanf("%d %d",&v,&n);
      for(int i = 1;i <= n;i ++)
          scanf("%d",&c[i]);
      for(int i = 1;i <= n; i ++)
          scanf("%d",&w[i]);
      for(int i = 1;i <= n;i ++)
      {
         for(int t = 0 ; t < c[i]; t++)
            { f[i][t] = f[i-1][t];
              p[i][t] = p[i-1][t];
            }
         for(int t = c[i]; t <= v; t++)
         {
             if(f[i-1][t] > f[i-1][t-c[i]]+w[i] )
             {
                f[i][t] = f[i-1][t];
                p[i][t] = p[i-1][t];
                g[i][t] = 0;

             }
             else if(f[i-1][t] < f[i-1][t-c[i]]+w[i]) 
             {
                
                 f[i][t] = f[i-1][t-c[i]]+w[i];
                 p[i][t] = p[i-1][t]+1;
                 g[i][t] = 1;
             }
             else
             {
                if(p[i-1][t] < p[i-1][t-c[i]]+1)
                {
                     f[i][t] = f[i-1][t-c[i]]+w[i];
                     p[i][t] = p[i-1][t]+1;
                     g[i][t] = 1;
                
                }
                else
                {
                     f[i][t] = f[i-1][t-c[i]]+w[i];
                     p[i][t] = p[i-1][t]+1;
                     g[i][t] = 0;
                
                }
             }
         }
      }
      int i = n ,r = 0;
      int t = v;
      int sumi = 0 , sum = 0;
      while(i > 0)
      {
           if(g[i][t] == 1)
           {
             k[r] = c[i];
             r++;
             t = t - c[i];
             sum++;
             sumi++;
           }
         i--;
      }

      qsort(k,r,sizeof(int),cmp);
      sum = k[0];
      tsum[0] = k[0];
      for(int h = 1;h < r;h ++)
      {
         tsum[h] = tsum[h-1]+k[h];
         sum = sum+tsum[h];
      }
     printf("%d %d %d\n",f[n][v],sumi,sum);
    }
  return 0;
}

 

posted on 2013-05-08 22:21  dark_dream  阅读(217)  评论(0编辑  收藏  举报