混合背包问题

xmuoj

#include<iostream>
#include<vector>
using namespace std;
typedef long long ll;
const int N = 5e6 + 4;
ll n, V, f[N], v[N], w[N], cnt[N];

struct Node
{
	ll v, w, cnt;
};

vector<Node>p;

void work()
{
	cin >> n >> V;   //物品种类数和背包体积
    for(int i = 1; i <= n; i++)
    {
    	ll v, w, c; cin >> v >> w >> c;  //体积,价值,数量
        if(c > 0)        //有限
        {
     		for(int k = 1; k <= c; k <<= 1)  //转化成单个背包,并利用可组合的性质
     		{
            	c -= k;
                p.push_back({k * v, k * w, -1}); 
            }
            if(c > 0)                       //凑不成单1,也加进去,为了凑出c
            {
            	p.push_back({c * v, c * w, -1});
            }
        }
        else p.push_back({v, w, c});   //1个或者无限
    }
  
    for(auto tmp: p)
    {
		if(tmp.cnt == -1)
		{
     		for(int k = V; k >= tmp.v; k--)
     		{
            	f[k] = max(f[k], f[k - tmp.v] + tmp.w); 
            }   
        }
        if(tmp.cnt == 0)
        {
        	for(int k = tmp.v; k <= V; k++)
        	{
            	f[k] = max(f[k], f[k - tmp.v] + tmp.w);
            }
        }    	
    }
    
    cout<<f[V];
}

posted @ 2022-03-25 10:19  兮何其  阅读(36)  评论(0)    收藏  举报