背包

P1048 [NOIP2005 普及组] 采药(01背包):

#include<bits/stdc++.h>
using namespace std;
int m,bag,dp[100005],t,w;
int main()
{
	scanf("%d%d",&bag,&m);
	for(int i = 1;i<=m;i++)
	{	
	scanf("%d%d",&t,&w);
	for(int j = bag;j>=t;--j)
		dp[j]=max(dp[j],dp[j-t]+w);
	}
	printf("%d",dp[bag]);
	return 0;
}

P1616 疯狂的采药(完全背包):

#include<iostream>
#include<cmath>
using namespace std;
long long int n,v,f[10000000],c[10000000],w[100000000],k;
int main()
{	
    cin>>v>>n;
	for(int i=1;i<=n;i++) cin>>c[i]>>w[i]; 

	for(int i=1;i<=n;i++)
		for(int j=c[i];j<=v;j++)
		f[j]=max(f[j],f[j-c[i]]+w[i]); 
	cout<<f[v];
	return 0;
} 

多重背包 P1776 宝物筛选(倍增(?)优化)

#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
using namespace std;
ll n,t,v,f[10000007],c[500005],w[500005],num[500005],ans;

int main()
{
	scanf("%lld%lld",&n,&v);
	for1(i,1,n) scanf("%lld%lld%lld",&w[i],&c[i],&num[i]);
   	for1(i,1,n)
	{
			ll mx=min(v/c[i],num[i]);
			for(ll k = 1;mx>0;k*=2)
			{
		    	if(k>mx) k=mx;
		    	for(int  j = v;j>=c[i]*k;j--)
		        {
		    	    f[j]=max(f[j],f[j-c[i]*k]+w[i]*k);
		        }
		        mx-=k;
		    }
	}
	printf("%lld",f[v]);
	return 0;
}

多重背包 P1776 宝物筛选(单调队列优化)

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i = a;i<=b;i++)
using namespace std;
int head,dl[500005],tail,n,m,w,v,num,dp[500005],ji[500005];//ji记录上一次循环时的dp数组 
int main()
{
	scanf("%d%d",&n,&m);
	for1(i,1,n)
	{
		scanf("%d %d %d",&v,&w,&num);
		for1(i,1,m)
		ji[i]=dp[i];
		for1(j,0,w-1)//j表示余数 
		{
			head=1,tail=0;
			for(int k=j;k<=m;k+=w) 
			{
				if(tail>=head&&(k-dl[head])/w>num)head++;//要保证加入物品后,队列的头选取的数量要小于等于s,如果大于s那就越界了.																
									//保证加入当前物品后,编号(体积)在给定的窗口之中,(k-dl[head]/v就是要加入物品的数量
				while(tail>=head&&(dl[tail]-k)/w*v+ji[k]>=ji[dl[tail]]) tail--;// 比较当前将要加入队列的元素和单调队尾相比,不单调就删队尾
				if(tail>=head)dp[k]=max(dp[k],ji[dl[head]]+(k-dl[head])/w*v);//更新 		  
				dl[++tail]=k;//入队	
			}
		}
	}
	cout<<dp[m]<<endl;
	return 0;
}

混合背包 P1833 樱花

#include<bits/stdc++.h>
#define for1(i,a,b) for(int i =a;i<=b;i++)
using namespace std;
int c,n,w,p,v[1000005],f[1000005],num[1000005],mx,ji;
int main()
{
	int nx,ny,ex,ey,n;
	scanf("%d:%d%d:%d%d",&nx,&ny,&ex,&ey,&n);
	int V=(ex*60+ey)-(nx*60+ny);
for (int i = 1; i <= n; i++)
 {
	cin >> c >> w >> p;
	if (p == 0) 
		for (int j = c; j <= V; j++)
			f[j] = max(f[j], f[j - c] + w);
	else if (p == -1) 
		for (int j = V; j >= c; j--)
			f[j] = max(f[j], f[j - c] + w);
	else { 
		int num = min(p, V / c);
		for (int k = 1; num > 0; k <<= 1) 
		{
			if (k > num) k = num;
			num -= k;
			for (int j = V; j >= c * k; j--)
				f[j] = max(f[j], f[j - c * k] + w * k);
		}
	}
}
cout<<f[V];
	return 0;
}

二维费用背包P1507 NASA的食物计划

#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
using namespace std;
ll n,t,v,f[1007][900],c2[500005],c[500005],w[500005],num[500005],ans;
ll m;
int main()
{
	scanf("%lld%lld",&v,&m);
	cin>>n;
	for1(i,1,n) scanf("%lld%lld%lld",&c[i],&c2[i],&w[i]);
   	for1(i,1,n)
		for(int  j = v;j>=c[i];j--)
		    for(int k = m;k>=c2[i];k--)
		    f[j][k]=max(f[j][k],f[j-c[i]][k-c2[i]]+w[i]);
	printf("%lld",f[v][m]);
	return 0;
}

分组背包P1757 通天之分组背包

#include<bits/stdc++.h>
#define for1(i,a,b) for(register ll i = a;i<=b;i++)
#define ll long long
#define mp(a,b) make_pair(a,b)
using namespace std;
ll n,t,v,f[5007],ji[2001][2001],c[5005],w[5005],num[5005],ans;
int main()
{
	ll x;
	scanf("%lld%lld",&v,&n);
	for1(i,1,n) scanf("%lld%lld%lld",&c[i],&w[i],&x),t=max(x,t),num[x]++,ji[x][num[x]]=i;
   	for(int i = 1;i<=t;i++)
   {
		for(int  j = v;j>=0;j--)
		    for(int k = 1;k<=num[i];k++)
		    if(j>=c[ji[i][k]])
		    f[j]=max(f[j],f[j-c[ji[i][k]]]+w[ji[i][k]]);
	}
	printf("%lld",f[v]);
	return 0;
}

有依赖的背包P1064 [NOIP2006 提高组] 金明的预算方案

#include<bits/stdc++.h>
using namespace std;
int n,v,f[200005],c[200005],w[200005],vis[200005];
vector < int > fj[200005];
int main()
{	
    cin>>v>>n;
    int x,y,z;
	for(int i=1;i<=n;i++) 
	{
		scanf("%d%d%d",&x,&y,&z);
		w[i]=x*y;
		c[i]=x;
		if(z!=0) fj[z].push_back(i),vis[i]=1;
	}
	for(int i=1;i<=n;i++)
	{
    	if(vis[i]==0)
    	{
	    	for(int j=v;j>=c[i];j--)
	    	{
		        f[j]=max(f[j],f[j-c[i]]+w[i]); 
		        if(fj[i].size()==1)
		        {
			    	if(j>=c[i]+c[fj[i][0]])
		            f[j]=max(f[j],f[j-c[i]-c[fj[i][0]]]+w[i]+w[fj[i][0]]); 
			     }
			    if(fj[i].size()==2)
			    {
			    	if(j>=c[i]+c[fj[i][0]])
		            f[j]=max(f[j],f[j-c[i]-c[fj[i][0]]]+w[i]+w[fj[i][0]]);
		            
		            if(j>=c[i]+c[fj[i][1]])
		            f[j]=max(f[j],f[j-c[i]-c[fj[i][1]]]+w[i]+w[fj[i][1]]);
		            
		            if(j>=c[i]+c[fj[i][0]]+c[fj[i][1]])
		            f[j]=max(f[j],f[j-c[i]-c[fj[i][1]]-c[fj[i][0]]]+w[i]+w[fj[i][0]]+w[fj[i][1]]);
			    }
		    }
	    }
	}
	cout<<f[v];

 } 

泛化物品(找不到题)

posted @ 2022-02-17 11:30  yyx525jia  阅读(22)  评论(0)    收藏  举报