UESTC 1691 这是一道比CCCC简单题经典的中档题 多重背包

117 篇文章 2 订阅
12 篇文章 0 订阅

这是一道比CCCC简单题经典的中档题

Time Limit: 4500/1500MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others)


Submit  Status
谭爷曾经是个很爱喝豆奶的男人,UESTC小卖部有N种豆奶,每种豆奶的数量为C1,C2......Cn。谭爷在抢劫小卖部的时候会从中任选若干件放在容量为W的谭爷巨型背包里,每种豆奶的体积为W1,W2......Wn(Wi为整数),与之相对应的价值为P1,P2......Pn(Pi为整数)。求背包能够容纳的豆奶最大价值。


Input

第1行,两个整数N和W,中间用空格隔开。N为豆奶的种类数,W为背包的容量。(1 <= N <= 100,1 <= W <= 50000) 第2 - N + 1行,每行3个整数Wi,Pi和Ci,分别是豆奶体积、价值和数量。(1 <= Wi, Pi <= 10000, 1 <= Ci <= 200)


Output

谭爷可以抢到的最大的豆奶价值之和。


Sample input and output
Sample Input Sample Output
3 6                                    9
2 2 5
3 3 8

1 4 1


Source

2017 UESTC Training for Dynamic Programming

UESTC 1691 这是一道比CCCC简单题经典的中档题

My Solution

多重背包
转化成0-1背包来跑。
for(i = 1; i <= n; i++){
    for(k = 0; k <= c[i]; k++){
        for(j = w; j >= 0; j--){
            if(j - k*need[i] >= 0) dp[i][j] = max(dp[i][j], dp[i-1][j-k*need[i]] + k*value[i]);
            else break;
        }
    }
    for(j = 0; j <= w; j++){
        if(j) dp[i][j] = max(dp[i][j], dp[i][j-1]);
    }
}
时间复杂度 O(n*sigma(ci))
空间复杂度 O(n^w)


#include <iostream>
#include <cstdio>

using namespace std;
typedef long long LL;
const int MAXN = 1e2 + 8, MAXM = 5e4 + 8;

int need[MAXN], value[MAXN], c[MAXN], dp[MAXN][MAXM];

template <class T>
inline void cinn(T &ret)
{
    char c=getchar();
    while(c<'0'||c>'9')
        c=getchar();
    ret=c-'0';
    while(c=getchar(),c>='0'&&c<='9')
        ret=ret*10+(c-'0');
}

int main()
{
    #ifdef LOCAL
    freopen("m.txt", "r", stdin);
    //freopen("m.out", "w", stdout);

    #endif // LOCAL
    //ios::sync_with_stdio(false); cin.tie(0);

    int n, w, i, j, k;
    //cin >> n >> w;
    //scanf("%d%d", &n, &w);
    cinn(n); cinn(w);
    for(i = 1; i <= n; i++){
        //cin >> need[i] >> value[i];
        //scanf("%d%d%d", &need[i], &value[i], &c[i]);
        cinn(need[i]); cinn(value[i]); cinn(c[i]);
    }
    for(i = 1; i <= n; i++){
        for(k = 0; k <= c[i]; k++){
            for(j = w; j >= 0; j--){
                if(j - k*need[i] >= 0) dp[i][j] = max(dp[i][j], dp[i-1][j-k*need[i]] + k*value[i]);
                else break;
            }
        }
        for(j = 0; j <= w; j++){
            if(j) dp[i][j] = max(dp[i][j], dp[i][j-1]);
        }
    }
    //cout << dp[n-1][w] << endl;
    printf("%d\n", dp[n][w]);
    return 0;
}


  Thank you!

                                                                                                                                            ------from ProLights

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值