zoukankan      html  css  js  c++  java
  • DP背包(一)

    01背包

    for(int i=0;i<n;i++) //遍历每一件物品
    	for(int j=v;j>=wei[i];j--)//遍历背包容量,表示在上一层的基础上,容量为J时,第i件物品装或不装的最优解;
    		dp[j]=max(dp[j-wei[i]]+val[i],dp[j]);
    

    初始化细节:装满dp[0]=0;其余赋值-INF;不装满全初始化为0;

    完全背包

    for(int i=0;i<n;i++) //遍历每一类物品
    	for(int j=wei[i];j<=v;j++)//遍历容量,此时代表第一类物品选了几件。与0/1区别正序遍历
    		dp[j]=max(dp[j-wei[i]]+val[i],dp[j]);
    

    多重背包

    for(int i=0;i<n;i++)  //遍历每一个物品 
    		   for(int j=0;j<=num[i];j++)  //遍历物品的数量 
    		      for(int k=m;k>=weight[i];k--)   //当做01背包来处理 
    		      {  //取01背包情况的dp[k]和dp[k-weight[i]]+value[i]的最大值 
    				dp[k]=max( dp[k],dp[k-weight[i]]+value[i] );
    			  }
    

    二进制优化
    优化原因:

    多重背包转换成 01 背包问题就是多了个初始化,把它的件数C 用
    分解成若干个件数的集合,这里面数字可以组合成任意小于等于C
    的件数,而且不会重复,之所以叫二进制分解,是因为这样分解可
    以用数字的二进制形式来解释
    比如:7的二进制 7 = 111 它可以分解成 001 010 100 这三个数可以
    组合成任意小于等于7 的数,而且每种组合都会得到不同的数
    15 = 1111 可分解成 0001 0010 0100 1000 四个数字
    如果13 = 1101 则分解为 0001 0010 0100 0110 前三个数字可以组合成
    7以内任意一个数,加上 0110 = 6 可以组合成任意一个大于6 小于13
    的数,虽然有重复但总是能把 13 以内所有的数都考虑到了,基于这种
    思想去把多件物品转换为,多种一件物品,就可用01 背包求解了。

    for(int i=0;i<n;i++)
    {
    	cin>>w[i]>>v[i]>>c[i];//对每一种类的c[i]件物品进行二进制分解
    	for(int j=1;j<=c[i];j<<=1){      //右移=*2 
    		value[cnt]=j*v[i];
    		weight[cnt]=j*w[i];
    		cnt++;
    		c[i]-=j; 
    	} 
    	if(c[i]>0){
    		alue[cnt]=c[i]*v[i];
    		weight[cnt]=c[i]*w[i];
    		cnt++;
    	}
    }
    01背包求解.....
    

    好像单调队列也能优化,多重背包;
    下一期整理

  • 相关阅读:
    关于程序中以时间判断接收数据结束时,接收数据长度设置为1时,出现接收不全的问题解释。
    stm32 外部8M晶振 改为12M的方法
    django iis 部署
    电信NB卡
    socketserver
    APScheduler简介
    三极管开关电路
    mysql授权
    解决VMware无法共享ubuntu虚拟机文件
    Python解析yaml配置文件
  • 原文地址:https://www.cnblogs.com/lunatic-talent/p/12798976.html
Copyright © 2011-2022 走看看