程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> CODEVS 3269 混合背包

CODEVS 3269 混合背包

編輯:C++入門知識

CODEVS 3269 混合背包


一道裸的混合背包題目,但是忘記了去重一直TLE,就是如果體積<=完全背包的01,和多重背包都要被完全背包取代,因為他的數量沒限制所以用起來更方便。

 

#include 
#include 
#include 
#include 
using namespace std;

const int maxn = 210;
const int maxc = 200010;


inline int read()
{
    char ch;
    bool flag = false;
    int a = 0;
    while(!((((ch = getchar()) >= '0') && (ch <= '9')) || (ch == '-')));
    if(ch != '-')
    {
        a *= 10;
        a += ch - '0';
    }
    else
    {
        flag = true;
    }
    while(((ch = getchar()) >= '0') && (ch <= '9'))
    {
        a *= 10;
        a += ch - '0';
    }
    if(flag)
    {
        a = -a;
    }
    return a;
}
void write(int a)
{
    if(a < 0)
    {
        putchar('-');
        a = -a;
    }
    if(a >= 10)
    {
        write(a / 10);
    }
    putchar(a % 10 + '0');
}

int f[maxc], v[maxn], w[maxn], m[maxn];
int n, V;
bool vis[maxn];

void complete_pack(int cost, int weight)
{
    for(int j = cost; j <= V; j++)
        f[j] = max(f[j], f[j-cost]+weight);
}

void zero_pack(int cost, int weight)
{
    for(int j = V; j >= cost; j--)
        f[j] = max(f[j], f[j-cost]+weight);
}

void multi_pack(int cost, int weight, int amount)
{
    if(cost*amount >= V)
    {
        complete_pack(cost, weight);
        return;
    }
    int k = 1;
    while(k < amount)
    {
        zero_pack(cost*k, weight*k);
        amount -= k;
        k <<= 1;
    }
    zero_pack(amount*cost, amount*weight);
}
int main()
{
    n = read();
    V = read();
    memset(vis, false, sizeof(vis));
    for(int i=1; i<=n; i++)
    {
        v[i] = read();
        w[i] = read();
        m[i] = read();
    }
    for(int i = 1; i <= n; i++)
    {
        for(int j = i+1; j <= n; j++)
        {
            if(m[i] == 1)
            {
                if(m[j] == -1)if(v[i] >= v[j] && w[i] <= w[j]) vis[i] = true;
                if(m[j] > 1)if(v[i] >= v[j] && w[i] <= w[j]) vis[i] = true;
            }
            else if(m[i] > 1)
            {
                if(m[j] == -1)
                if(v[i] >= v[j] && w[i] <= w[j]) vis[i] = true;
            }
        }
    }
    for(int i=1; i<=n; i++)
    {
        if(m[i]==1 && !vis[i])
            zero_pack(v[i], w[i]);
        else if(m[i]==-1)
            complete_pack(v[i], w[i]);
        else if(!vis[i])multi_pack(v[i], w[i],m[i]);
    }
    write(f[V]);
    return 0;
}


 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved