分组背包的拓展

一.至多选一个

点击查看代码

#include"bits/stdc++.h"
using namespace std;
int main()
{
	for(i = 0; i < n; i++) //n是总共种类
	    for(j = vmax; j >= 0; j--) //vmax是背包最大容量
	        for(k = 0; k < num[i]; k++) //num[]为该类物品个数 
	            if(j >= v[k]) dp[i][j] = max(dp[i][j], dp[i-1][j-v[k]]+w[k]);
}

二.至少选一个

点击查看代码

#include"bits/stdc++.h"
using namespace std;
int main()
{
	memset(dp, -1, sizeof(dp));
	dp[0][0] = 0;
	for(i = 1; i <= n; i++) //n是总共种类
	{
	    for(k = 0; k < num[i]; k++) //num[]为该类物品个数 
	    {
	        for(j = vmax; j >= v[k]; j--) //vmax是背包最大容量
	        {
	            if(dp[i][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
	            if(dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
	        }
	    }
	}
}

三.每组随便选

点击查看代码
#include"bits/stdc++.h"
using namespace std;
int main()
{
	memset(dp, -1, sizeof(dp));
	dp[0][0] = 0;
	for(i = 1; i <= n; i++)//n是总共种类
	{
	 
	    for(k = 0; k < num[i]; k++) //num[]为该类物品个数 
	    {
	        for(j = vmax; j >= v[k]; j--) //vmax是背包最大容量
	        {
	            if(dp[i][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
	            if(dp[i-1][j-v[k]] != -1) dp[i][j] = max(dp[i][j], dp[i][j-v[k]]+w[k]);
	        }
	        for(j = 0; j <= vmax; j++)
	        {
	        	dp[i][j] = max(dp[i][j], dp[i-1][j]);
			}
	    }
	}
}

来个大杂烩

点击查看代码
#include"iostream"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"algorithm"
using namespace std;

const int N=200;
int n,m;
int f[N][N];
int v[N],w[N];

int main()
{
	while(scanf("%d%d",&n,&m)!=EOF)
	{
		memset(f,-1,sizeof f);
		memset(f[0],0,sizeof f[0]);
				
		for(int i=1;i<=n;i++)
		{
			int num,op;
			scanf("%d%d",&num,&op);
			for(int j=1;j<=num;j++)
			{
				scanf("%d%d",&v[j],&w[j]);			
			}
			if(op==0)
			{
				for(int j=1;j<=num;j++)
				{
					for(int k=m;k>=v[j];k--)
					{
						if(f[i][k-v[j]]!=-1)
						{
							f[i][k]=max(f[i][k],f[i][k-v[j]]+w[j]); 
						}
						if(f[i-1][k-v[j]]!=-1)
						{
							f[i][k]=max(f[i][k],f[i-1][k-v[j]]+w[j]);
						}
					}
				}
			}
			else if(op==1)
			{
				for(int k=0;k<=m;k++)
				{
					f[i][k]=f[i-1][k];
				}
				for(int j=1;j<=num;j++)
				{
					for(int k=m;k>=v[j];k--)
					{
						if(f[i-1][k-v[j]]!=-1)
						{
							f[i][k]=max(f[i][k],f[i-1][k-v[j]]+w[j]);
						}
					}
				}
			}
			else if(op==2) 
			{
				for(int k=0;k<=m;k++)
				{
					f[i][k]=f[i-1][k];
				}
				for(int j=1;j<=num;j++)
				{
					for(int k=m;k>=v[j];k--)
					{
						if(f[i][k-v[j]]!=-1)
						{
							f[i][k]=max(f[i][k],f[i][k-v[j]]+w[j]);
						}
					}
				}
			}
		}
		printf("%d\n",f[n][m]);
	}
}
posted @ 2024-07-11 14:58  zhengchenxi  阅读(29)  评论(0)    收藏  举报