TOJ2671 01-package

01-package 分享至QQ空间 去爱问答提问或回答

Time Limit(Common/Java):1000MS/10000MS     Memory Limit:65536KByte
Total Submit: 41            Accepted: 17

Description

给定一个背包的容量k,给定n个物品的体积和价值,物品不可分割,将n个物品中选若干个物品放入背包,求背包内物品的最大价值总和,在价值总和最大的前提下求背包内的最小物品个数c。

Input

第一行是一个整数t,表示测试数据的组数t。
对于每组测试数据,第一行是两个整数n和k,表示物品的个数和背包的容量;
接下来n行,每行两个整数,分别是物品的价值和体积。所有整数都不超过1000。

Output

输出背包内物品的最大价值v,在价值最大的前提下求背包内的最小物品个数c,中间用一个空格隔开。

Sample Input

1
3 10
4 5
6 5
10 10

Sample Output

10 1
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int maxn = 1100;

struct info {
    int v; // value;
    int w; //weight
};

vector<info> d(maxn);
int n, weight;//weight -> k
int f[maxn];
int cnt[maxn];

bool cmp(const info& x, const info& y) {
    return x.w > y.w;
}

void DP() {
    int i, j;
    for(i = 0; i < n; i++) {
        for(j = weight; j >= d[i].w; j--) {
            if(f[j] >= f[j-d[i].w] + d[i].v) {
                f[j] = f[j];
            }
            else {
                f[j] = f[j-d[i].w] + d[i].v;
                cnt[j] = cnt[j-d[i].w] + 1;
            }
        }
    }
    printf("%d %d\n", f[weight], cnt[weight]);
}

void init() {
    memset(f, 0, sizeof(f));
    memset(cnt, 0, sizeof(cnt));
    d.clear();
}

int main()
{
    int T, i;
    info tmp;
    scanf("%d", &T);
    while(T--) {
        init();
        scanf("%d%d", &n, &weight);
        for(i = 1; i <= n; i++) {
            scanf("%d%d", &tmp.v, &tmp.w);
            d.push_back(tmp);
        }
        sort(d.begin(), d.end(), cmp);//保证其数量最小.
        DP();
        init();
    }
    return 0;
}

你可能感兴趣的:(TOJ2671 01-package)