背包模板
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;
}
[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;
}
相关文章推荐
- 01背包模板、完全背包 and 多重背包(模板)
- 背包的优化模板
- 多重背包二进制优化模板
- HDU - 2191悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包模板题)
- HDU ACM 2844 Coins (多重背包)----------------01背包,完全背包,多重背包模板
- Bone Collector(01背包模板题)
- POJ 1276 Cash Machine ( 多重背包模板题目 )
- 杭电-1248 寒冰王座(完全背包模板)
- 51nod 1086 多重背包模板
- 背包小模板
- 各种背包模板
- hdu 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活(多重背包模板题)
- SDUT OJ I样(0-1背包问题 【模板】)
- 背包模板
- HDU 2191 512大地震 【多重背包模板题】
- 多重背包 模板
- hpu 2191 悼念512汶川大地震遇难同胞——珍惜现在,感恩生活 【多重背包模板】
- 【多重背包模板】poj 1014
- 背包DP的标准代码模板
- 初级背包模板