经典皇冠备用网址 01背包+完全背包+多重背包 - X-POWER

2019-04-13 14:19  来自: 网络整理

01 背包

有n 差数文字,每个工程都有两个属性。,size 音量,value 财产,如今赡养每一使使臻于完善 w 背包,问问有大约财产可以被拿走。。  

  

1for (int i=0; i)
2for (int j=w; j>=size[i]; j--)
3         f[j] = max(f[j], F[J-大多数[i] ]  值[I]

全背包

倘若工程不计算,它不光仅是每一工程。,简略地一划交替便了。  

1for (int i=0; i)
2for (int j=size[i]; j<=w; j++)
3         f[j] = max(f[j], F[J-大多数[i] ]  值[I]

     f[w] 这执意必要条件。  
设定初值可以分为两种经济状况。:
1、倘若背包恳求露骨地被装满,则设定初值它。 f[0] = 0, f[1~w] = -INF;  

        2、倘若批评,就把它猛吃。 f[0~v] = 0;  

        插图画家:

01背包

V=10,N=3,c[]={3,4,5}, w={4,5,6}

(1)背包未必是满的。

      计算挨次为:从右往左,从天而降:因每个工程但是座位一次。,较小的前部会效果音量。

(2)背包露骨地满。    

      计算挨次为:从右往左,从天而降。在意起始值,INF表现负无穷大。

全背包:

V=10,N=3,c[]={3,4,5}, w={4,5,6}

(1)背包未必是满的。

计算挨次为:从左往右,从天而降: 每个工程可以座位屡次。,前面会效果前面。

(2)背包露骨地满。

计算挨次为:从左往右,从天而降。在意起始值,INF表现负无穷大。

多重的背包:  
多重的皇冠备用网址必要条件很简略,也执意说,每个工程都赡养了精确的数字。,求最大引起值  
多背包交换 01 皇冠备用网址执意多了个设定初值,C的数字 一组二元系数除号多少数字。,数字可以分为不足或本利积和C的任性数。,它不能的重复。,它高地二元重新计算。,这是因重新计算可以用二元系表格解说。  
比方:7二元系 7 = 111 它可以重新计算成 001 010 100 这三数字字可以结成为不足或本利积和7。 的数,每个结成会赢得差数的数字。  
15 = 1111 可重新计算成 0001  0010  0100  1000 四数字字  
倘若13 = 1101 被重新计算成 0001 0010 0100 0110 前三数字字可以结成成每一。 7里边的数字。,即1、2、4可以结成成1到7的迷住数字。,补充部分 0110 = 6 可以结成成大于6的无论哪个每一。 不足或本利积和13的数字。,比如,12,你可以奉献6,这么奉献6。。不过有重复,但它不变的可以翻转。 13 迷住的数字都要思索在内。,本很模糊想法将多个工程转变为,多种一件使受协议条款的约束,你可以用01。 背包处理。  
看行为准则:  

int n;  //有大约工程是出口的?int c;  //每个工程有大约个工程?int v;  //每个工程的财产int s;  //每个工程的大多数int count = 0; //重新计算后可以赢得大约项?int 值[最高的] //用于保鲜重新计算工程的值int 量纲[最大]  //用于保鲜重新计算项的音量。
scanf("%d", &n);    //先有大约工程是出口的?,接下来,咱们对每个工程举行重新计算。while (n--)     //接下来,输出n中间的项。{
    scanf("%d%d%d", &c, &s, &v);  //输出每个工程的数字和值。for (int k=1; k<=c; k<<=1)   //<<右移 相当于乘二    {
        财产[计数] = k*v;
        量纲[计数]++] = k*s;
        c -= k;
    }
    if (c > 0)
    {
        财产[计数] = c*v;
        量纲[计数]++] = c*s;
    }
}

定理:无符号约整数n可以重新计算为1。,2,4,…,2^(k-1),n-2 ^ k 1(k是使臻于完善n-2 ^ k 1>0的最大约整数),1到n内的迷住约整数可以独占的地表现为1。,2,4,…,2^(k-1),N-2^ K 1中多少数的和表格。

检定如次:

(1) 1号,2,4,…,2^(k-1),n-2 ^ k 1中迷住元素积和为n。,照着,少数元素和的和是:[1, n];

(2)倘若无符号约整数T<= 2^k – 1,则t一定能用1,2,4,…,2^(k-1)中某几数字的和表现,很很容易检定:咱们把t的二元系表现写出来,很明显,t可以表现成n=a0*2^0+a1*2^1+…+ak*2^(k-1),其中ak=0或者1,表现t的第ak位二元系数为0或者1.

(3)倘若t>=2 ^ k,设s=n-2^k+1,这么T-S<=2^k-1,因而t-s可以表现成1,2,4,…,2^(k-1)中某几数字的和的表格,进而t可以表现成1,2,4,…,2^(k-1),s中某几数字的和(加数中一定含有s)的表格。

(证明执行)!)

        如今应用计数 替代 n 就和01 皇冠备用网址完整同上了  

杭电2191解:此为多重的背包用01和全背包:

#include
#include<string.h>
int dp[102];
int p[102],h[102],c[102];
int n,m;
void 康贝克int v,int w)//基金,分量。全背包;{
    for(int i=v; i<=n; i++)
        if(DP[I])w)
            DP[I]DP[I-V]w;
}
void oneback(int v,int w)//基金,分量;01背包;{
    for(int i=n; i>=v; i--)
        if(DP[I])w)
            DP[I]DP[I-V]w;
}
int main()
{
    int ncase,i,j,k;
    scanf("%d",&ncase);
    while(ncase--)
    {
        memset(dp,0,sizeof(DP)
        scanf("%d%d",&n,&m);//基金,等级;for(i=1; i<=m; i++)
        {
            scanf("%d%d%d",&p[i],&h[i],&c[i]);//财产,分量,数字;if(p[i]*c[i]>=n) 康贝克p[i],h[i]);
            else
            {
                for(j=1; j1)
                {
                    oneback(j*p[i],j*h[i]);
                    c[i]=c[i]-j;
                }
                oneback(p[i]*c[i],h[i]*c[i]);
            }
        }
        printf("%d
",dp[n]
    }
    return0;
}



下一篇:没有了

更多>>

相关资讯

  • 亚洲地图高清版下载|亚

  • 皇冠备用网址市 - 廊坊市

  • 皇冠备用网址市卫星地图

  • 【景观】世界各地的一些

推荐资讯 更多>>

Copyright © 2016-2017皇冠备用网址 - 皇冠投注网址 - 皇冠娱乐网 版权所有


扫一扫访问移动端