zoukankan      html  css  js  c++  java
  • 湖大训练赛第三场 Happy Programming Contest

    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;
    }
    没有梦想,何谈远方
  • 相关阅读:
    指针类型
    集合类型
    VMware打开虚拟机没反应的解决方案(全面汇总)
    redis主从|哨兵|集群模式
    MYSQL一次千万级连表查询优化
    StackExchange.Redis通用封装类分享
    Redis-五种数据类型解析
    Redis并发问题
    C#委托和事件
    Invoke 和 BeginInvoke 的区别
  • 原文地址:https://www.cnblogs.com/zyue/p/3067934.html
Copyright © 2011-2022 走看看