背包基础
一、01背包基础模板
有重量有价值;或者有重量无价值的(可以将价值定义为和重量相同的数值)
物品只可装入一次
#include<iostream>
#include<algorithm>
using namespace std;
int dp[100005]; //dp数组定义为全局变量防止因越界而导致程序无法运行
int main()
{
int t,m,i,j; // t为背包容量,m为多少个物品
int w[105],v[105];
cin>>t>>m;
for(i=1;i<=m;i++)
{
cin>>w[i]>>v[i];
}
for(i=1;i<=m;i++)
{
for(j=t;j>=w[i];j--) //当当前背包容量大于或者等于i物体的重量时,考虑是否装入背包,达到最大价值
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<dp[t]<<endl;
return 0;
}
该代码对应题目:https://www.luogu.com.cn/problem/P1048
二、 完全背包基础模板
物品可以装入多次
#include<iostream>
#include<algorithm>
using namespace std;
long long dp[100000005]; //dp数组定义为全局变量防止因越界而导致程序无法运行
int main()
{
long long t,m,i,j; //t为背包容量,m为多少个物品
long long w[100005],v[100005];
cin>>t>>m;
for(i=1;i<=m;i++)
cin>>w[i]>>v[i];
for(i=1;i<=m;i++)
{
for(j=w[i];j<=t;j++)
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
cout<<dp[t]<<endl;
return 0;
}
该代码对应题目:https://www.luogu.com.cn/problem/P1616
三、混合背包
有的物品可多次,有的物品无限次
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int dp[1000005];
int n,k,m[1000005],v[1000005];
int t[10005],c[10005],p[10005];
void pre()
{
for(int i=1;i<=n;i++)
{
int j=1;
while(p[i])
{
m[++k]=j*t[i];
v[k]=j*c[i];
p[i]-=j;
j*=2;
if(p[i]<=j) //如果剩下的不能再拆,就直接放在一起
{
m[++k]=t[i]*p[i];
v[k]=c[i]*p[i];
break;
}
}
}
}
int main()
{
int hh1,mm1,hh2,mm2,time;
scanf("%d:%d%d:%d%d",&hh1,&mm1,&hh2,&mm2,&n);
time=(hh2*60+mm2)-(hh1*60+mm1);
for(int i=1;i<=n;i++)
{
cin>>t[i]>>c[i]>>p[i];
if(p[i]==0)
p[i]=999999;
}
pre(); //二进制拆分
for(int i=1;i<=k;i++)
for(int j=time;j>=m[i];j--)
dp[j]=max(dp[j],dp[j-m[i]]+v[i]);
cout<<dp[time]<<endl;
return 0;
}