BIT 1094 Ahui Writes Word

本文针对一个特定的多重背包问题进行了解析,通过分析题目特点,将01背包问题转化为多重背包问题,并给出了详细的C语言实现代码。文章展示了如何处理大量重复物品的场景,通过具体的编程实现来解决该类问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目大意:给你N个字符串(N<100000),以及上限复杂度C(C<100000),每个字符串的价值为v[i],复杂度为c[i],(0<=v[i],c[i]<=10)现在要求在总复杂度和不超过C的情况下得到尽量大的价值。

 

考察点:DP

 

思路分析:虽然一眼就知道是个01背包,但是一开始看到N和C的范围傻眼了。。后来再看c[i]跟v[i]的范围,可以发现这其中肯定有大量重复的,所以01背包就转变成多重背包啦

 

#include<stdio.h>
#define max(x,y) (x)>(y)? (x):(y)

int c[15][15];
int f[10010];
char str[21];
int t,m,n;

void zeroonepack(int x,int y)
{
  int i;
  for (i=m;i>=x;i--)
    f[i]=max(f[i],f[i-x]+y);
}
     
void complepack(int x,int y)
{
     int i;
     for (i=x;i<=m;i++)
       f[i]=max(f[i],f[i-x]+y);
}

void multiplepack(int x,int y,int z)
{
  if (x*z>=m) complepack(x,y);
  else {
         int k=1;
         while (k<z)
         {
           zeroonepack(x*k,y*k);
           z=z-k;
           k=k*2;
         }
         zeroonepack(z*x,z*y);
       }
}
     
int main()
{
    int i,j,x,y;
    while(scanf("%d%d",&t,&m)!=EOF)
    {
    memset(f,0,sizeof(f));
    memset(c,0,sizeof(c));
    n=0;
    for (i=1;i<=t;i++)
    {
      scanf("%s%d%d",str,&x,&y);
      c[x][y]++;
    }
    for (i=0;i<=10;i++)
      for (j=0;j<=10;j++)
          if (c[i][j]!=0)
            multiplepack(j,i,c[i][j]);
    printf("%d\n",f[m]);
    }
    return 0;
}
    
    
    
    
    
    


 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值