您的位置:首页 > 其它

背包模板

2017-10-26 15:31 120 查看
模板:

[cpp] view
plain copy

/** 

*  多重背包: 

*  有N种物品和一个容量为 V的背包。第i种物品最多有 num[i]件可用, 

* 每件耗费的空间是C[i],价值是W[i]。 

* 求解将哪些物品装入背包可使这些物品的耗费的空间总和不超过背包容量,且价值总和最大。 

*/  

#include <iostream>  

#include <cstring>  

#include <algorithm>  

using namespace std;  

#define maxn 100005  

int c[maxn], w[maxn], num[maxn];//c:费用 w:价值 num:数量  

int dp[maxn];    //当前位置符合题意的最优解         

int V;               //V:总容量  

  

//01背包  

void ZeroOnePack(int c, int w)  

{  

    for (int v = V; v >= c; v--)  

    {  

        dp[v] = max(dp[v], dp[v - c] + w);  

    }  

}  

//完全背包  

void CompletePack(int c, int w)  

{  

    for (int v = c; v <= V; v++)  

    {  

        dp[v] = max(dp[v], dp[v - c] + w);  

    }  

}  

//多重背包
1eac8
  

void MultiplePack(int c, int w, int num)  

{  

    if (c * num >= V)  

    {  

        CompletePack(c, w);  

    }  

    else  

    {  

        int k = 1;  

        while (k < num)  

        {  

            ZeroOnePack(k*c, k*w);  

            num -= k;  

            k <<= 1;  

        }  

        ZeroOnePack(num*c, num*w);  

    }  

}  

int main()  

{  

    int t;  

    cin>>t   

    while (t--)  

    {  

        int n;  

        scanf("%d%d", &V, &n);  

        for (int i = 1; i <= n; i++)  

            cin>>c[i]>>w[i]>>num[i];  

        memset(dp, 0, sizeof(dp));  

        for (int i = 1; i <= n; i++)  

            MultiplePack(c[i], w[i], num[i]);  

        cout<<dp[V];  

    }  

    return 0;  

}  

01背包:

[cpp] view
plain copy

/*  

01背包问题  

01背包问题的特点是,每种物品仅有一件,可以选择放或不放。  

01背包问题描述:  

有N件物品和一个容量为 V的背包。第i件物品的重量是w[i],价值是v[i]。  

求解将哪些物品装入背包可使这些物品的重量总和不超过背包容量,且价值总和最大。 

poj 3624  

*/    

#include<iostream>  

#define N 1000005  

#include<algorithm>  

#include<cstring>  

using namespace std;      

int w
,v
,dp
;    

int main()    

{    

    int i, j, n, m;    

    while(cin>>n)  //n件物品   

    {    

        cin>>m;//容积为m   

        memset(dp,0,sizeof(dp));   

        for(i=0; i<n; i++)    

            cin>>w[i]>>v[i];//w[i]为重量,v[i]为价值    

        for(i=0; i<n; i++)    

        {    

            for(j=m; j>=w[i]; j--) //选与不选两条途径   

                dp[j] = max(dp[j], dp[j-w[i]]+v[i]);    

        }    

        cout<<dp[m];  

    }    

    return 0;    

}    

完全背包:

[cpp] view
plain copy

/*  

完全背包问题的特点是,每种物品可以无限制的重复使用,可以选择放或不放。  

完全背包问题描述:  

有N物品和一个容量为 V的背包。第i件物品的重量是w[i],价值是v[i]。  

//此代码为HDU1114;  

*/    

#include <iostream>    

#include <algorithm>  

#define INF 0x3fffffff    

#define N 10047    

using namespace std;  

int dp
,v
,w
;    

int main()    

{    

    int t,i,j,k,e,f,m,n;    

    cin>>t;   

    while(t--)    

    {    

        cin>>e>>f;    

        int c = f-e;    

        for(i = 0 ; i <= c ; i++)    

            dp[i]=INF;    

        cin>>n;    

        for(i = 0 ; i < n ; i++)    

        {    

            cin>>v[i]>>w[i];//v[i]为价值,w[i]为重量    

        }    

        dp[0]=0;  

        //注意初始化(要求恰好装满背包,那么在初始化时除了dp[0]为0其它f[1..V]均设为-∞,    

        //这样就可以保证最终得到的dp  是一种恰好装满背包的最优解。    

        //如果并没有要求必须把背包装满,而是只希望价格尽量大,初始化时应该将f[0..V]全部设为0)    

        for(i =0 ; i < n ; i++)  //n为物品种类数   

        {    

            for(j = w[i] ; j <= c ; j++)  //c为最大容积   

            {    

                dp[j] = min(dp[j],dp[j-w[i]]+v[i]);//此处求的是最坏的情况所以用min,确定最少的钱   

            }    

        }    

        if(dp[c] == INF)    

            printf("This is impossible.\n");    

        else    

            printf("The minimum amount of money in the piggy-bank is %d.\n",dp[c]);    

    }    

    return 0;    

}    

   

多重背包:

[cpp] view
plain copy

//多重背包(MultiplePack): 有N种物品和一个容量为 V的背包。    

//第i种物品最多有num[i]件可用,每件费用是pre[i],价值是w[i]。    

//求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,    

//且价值总和最大。     

//hdu 2191   

#include<iostream>    

#include<algorithm>    

#include<cstring>  

#define N 1005    

using namespace std;  

int main()    

{    

    int t,n,m,i,j,k;    

    int w
,pri
,num
,dp
;//dp存的是当前符合题意最大价值,pre[i]所需容积,w[i]价值;   

    while(cin>>t)  

    {    

        while(t--)    

        {    

            memset(dp,0,sizeof(dp));    

            cin>>n>>m;//n为总金额,m为大米种类    

            for(i = 0 ; i < m ; i++) //m种类总数   

            {    

                cin>>pri[i]>>w[i]>>num[i];//num[i]为每种物品的数量,pre[i]所需容积,w[i]价值   

            }    

            for(i = 0 ; i < m ; i++) // m为总种类数   

            {    

                for(j = 0 ; j < num[i] ; j++)  //num[i]为每种物品的数量,  

                {    

                    for(k = n ; k >= pri[i]; k--)  //pre[i]所需容积  

                    {    

                        dp[k] = max(dp[k],dp[k-pri[i]]+w[i]);    

                    }    

                }    

            }    

            cout<<dp
<<endl;    

        }    

    }    

    return 0;    

}    
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: