1. 程式人生 > >多重揹包SDNUOJ 1520

多重揹包SDNUOJ 1520

Description
SQK上山去採藥。SQK有一個容量為m(1<=m<=1000)的揹包,他所採集的藥材的總重量不能大於揹包的容量。已知共有n(1<=n<=100 )種藥材,每種藥材都有自己的價值,並且知道每種藥材的數量是有限的,如何選擇,才能使得揹包中藥材價值最大?

Input
輸入資料首先包含一個正整數C(1<=C<=10),表示有C組測試用例,每組測試用例的第一行是兩個整數m和n(1<=m<=1000, 1<=n<=100),分別表背包的負重和藥材的種類,然後是n行資料,每行包含3個數w,v和c(1<=w<=100,1<=v<=200,1<=c<=100),分別表示每種藥材的重量、每株的價值以及對應種類藥材的株數。

Output
對於每組測試資料,請輸出能夠採集藥材的最大價值,每個例項的輸出佔一行。

Sample Input
1
8 2
2 100 4
4 100 2
Sample Output
400

#include<iostream>
#include<cstring>
#include<cmath>
#include<algorithm>
using namespace std;
#define N 1005
///單價, 重量, 袋數
int p[N], w[N], num[N];
///該經費對應的最大重量
int m[N];

int main()
{
    int t;
    cin >> t;
    while(t--)
    {
        int c, n;
        cin >> c >> n;
        for(int i = 1; i <= n; i++)
            cin >> p[i] >> w[i] >> num[i];
        memset(m, 0, sizeof(m));
        ///對第i個物品的檢測
        for(int i = 1; i <= n; i++)
        {
            ///對第i個物品檢測次數 = 其現有數目(相當於0-1揹包多了幾個種類)
            for(int k = 0; k < num[i]; k++)
            {
                ///在0-1揹包基礎上的改動,因此為逆序列舉
                for(int j = c; j >= p[i]; j--)
                    m[j] = max(m[j],m[j-p[i]] + w[i]);
            }
        }
        cout << m[c] << '\n' ;
    }
    return 0;
}