poj 1742 多重背包(单调队列)

2024-04-28 17:32

本文主要是介绍poj 1742 多重背包(单调队列),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

 

如题:http://poj.org/problem?id=1742

 

,...又是这道题 ,第一种方法是二进制拆分多重背包(能过hdu2488 见我这一篇http://blog.csdn.net/twenty_seven/article/details/43152441),

       第二种是为了减小时间复杂度,通过改变dp策略(能过poj1742 不能过杭电)http://blog.csdn.net/twenty_seven/article/details/43159861,

       这里说第三种,多重背包的0(VN)复杂度算法。使用了单调队列。

      这位大牛写的很清楚http://blog.csdn.net/flyinghearts/article/details/5898183。

      也就是找出状态转移方程中的重复状态,然后将容量拆成v拆成余数和整数部分。通过等间距的几步的最大值推出下一个状态。

 

 

    

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;


int w[103];
int num[103];
int f[100005],q[100005];
int n,m;
int main()
{
// freopen("C:\\1.txt","r",stdin);
 while(~scanf("%d%d",&n,&m)&&n&&m)
 {
  int i,j,d;
  memset(f,0,sizeof(f));
  for(i=1;i<=n;i++)
   scanf("%d",&w[i]);
  for(i=1;i<=n;i++)
   scanf("%d",&num[i]);
  f[0]=1;
  int ret=0;
  for(i=1;i<=n;i++)
  {
   if(num[i]==1){
    for(j=m;j>=w[i];j--){
     if(!f[j]&&f[j-w[i]])
     {
      f[j]=1;
      ret++;
     }
    }
   }
   else if(num[i]*w[i]>=m)
   {
    for(j=w[i];j<=m;j++)
     if(!f[j]&&f[j-w[i]])
     {
      f[j]=1;
      ret++;
     }
   }
   else
   {
    for(d=0;d<w[i];d++)
    {
     int st=0,ed=-1,sum=0;
     for(j=d;j<=m;j+=w[i])
     {
      if(st+num[i]==ed)
       sum-=q[st++];
      q[++ed]=f[j];
      sum+=f[j];
      if(!f[j]&&sum)
      {
       f[j]=1;
       ret++;
      }
     }
    }
   }
  }
  printf("%d\n",ret);
 }
}

 

 

   

这篇关于poj 1742 多重背包(单调队列)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/943827

相关文章

如何通过Python实现一个消息队列

《如何通过Python实现一个消息队列》这篇文章主要为大家详细介绍了如何通过Python实现一个简单的消息队列,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下... 目录如何通过 python 实现消息队列如何把 http 请求放在队列中执行1. 使用 queue.Queue 和 reque

解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)

《解读Redis秒杀优化方案(阻塞队列+基于Stream流的消息队列)》该文章介绍了使用Redis的阻塞队列和Stream流的消息队列来优化秒杀系统的方案,通过将秒杀流程拆分为两条流水线,使用Redi... 目录Redis秒杀优化方案(阻塞队列+Stream流的消息队列)什么是消息队列?消费者组的工作方式每

Pandas中多重索引技巧的实现

《Pandas中多重索引技巧的实现》Pandas中的多重索引功能强大,适用于处理多维数据,本文就来介绍一下多重索引技巧,具有一定的参考价值,感兴趣的可以了解一下... 目录1.多重索引概述2.多重索引的基本操作2.1 选择和切片多重索引2.2 交换层级与重设索引3.多重索引的高级操作3.1 多重索引的分组聚

Redis延迟队列的实现示例

《Redis延迟队列的实现示例》Redis延迟队列是一种使用Redis实现的消息队列,本文主要介绍了Redis延迟队列的实现示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习... 目录一、什么是 Redis 延迟队列二、实现原理三、Java 代码示例四、注意事项五、使用 Redi

hdu1180(广搜+优先队列)

此题要求最少到达目标点T的最短时间,所以我选择了广度优先搜索,并且要用到优先队列。 另外此题注意点较多,比如说可以在某个点停留,我wa了好多两次,就是因为忽略了这一点,然后参考了大神的思想,然后经过反复修改才AC的 这是我的代码 #include<iostream>#include<algorithm>#include<string>#include<stack>#include<

poj2576(二维背包)

题意:n个人分成两组,两组人数只差小于1 , 并且体重只差最小 对于人数要求恰好装满,对于体重要求尽量多,一开始没做出来,看了下解题,按照自己的感觉写,然后a了 状态转移方程:dp[i][j] = max(dp[i][j],dp[i-1][j-c[k]]+c[k]);其中i表示人数,j表示背包容量,k表示输入的体重的 代码如下: #include<iostream>#include<

hdu2159(二维背包)

这是我的第一道二维背包题,没想到自己一下子就A了,但是代码写的比较乱,下面的代码是我有重新修改的 状态转移:dp[i][j] = max(dp[i][j], dp[i-1][j-c[z]]+v[z]); 其中dp[i][j]表示,打了i个怪物,消耗j的耐力值,所得到的最大经验值 代码如下: #include<iostream>#include<algorithm>#include<

csu(背包的变形题)

题目链接 这是一道背包的变形题目。好题呀 题意:给n个怪物,m个人,每个人的魔法消耗和魔法伤害不同,求打死所有怪物所需的魔法 #include<iostream>#include<algorithm>#include<cstring>#include<stack>#include<queue>#include<set>//#include<u>#include<map

hdu1011(背包树形DP)

没有完全理解这题, m个人,攻打一个map,map的入口是1,在攻打某个结点之前要先攻打其他一个结点 dp[i][j]表示m个人攻打以第i个结点为根节点的子树得到的最优解 状态转移dp[i][ j ] = max(dp[i][j], dp[i][k]+dp[t][j-k]),其中t是i结点的子节点 代码如下: #include<iostream>#include<algorithm

hdu1171(母函数或多重背包)

题意:把物品分成两份,使得价值最接近 可以用背包,或者是母函数来解,母函数(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v)(1 + x^v+x^2v+.....+x^num*v) 其中指数为价值,每一项的数目为(该物品数+1)个 代码如下: #include<iostream>#include<algorithm>