Day2 1517. 背包问题

Input

第一行为两个用空格隔开的正整数v和T。表示背包的空间和物品的组数。接下来有T行,每行先是一个正整数ni,表示这组物品有ni个,然后ni个正整数,表示每个物品的大小。

Output

仅一个数,表示剩余空间的最小值。

Sample Input

100 3
3 7 6 8
2 80 70
4 101 108 103 150

Sample Output

6

Data Constraint

Hint

【样例说明】
第1组选6、8,第2组选80,第3组不选。
【限制】
60%的数据满足:1 <= ni <= 10
100%的数据满足:1 <= ni <= 100,1<=v<=5000,1<=T<=10

做法:预处理所有的可能取的值,那不就是01背包了嘛
代码如下:

#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#define rep(i, a, b)    for(int i = a; i <= b; i++)
#define N 6007
#define ni 107
#define ll long long
using namespace std;
bool f[20][N];
int a[ni], s[12];
int n, m;
ll d[12][ni * ni], z[ni * ni];

int min(int a, int b){ return a < b ? a : b; }

int main()
{
    scanf("%d%d", &m, &n);
    rep(i, 1, n)
    {
        int t;
        memset(a, 0, sizeof(a));
        memset(z, 0, sizeof(z));
        scanf("%d", &t);
        rep(j, 1, t)
            scanf("%d", &a[j]);
        int tot = 0;
        rep(j, 1, t)
        {
            z[++tot] = a[j];    
            rep(k, j + 1, t)
                if (j < t)  z[++tot] = z[tot - 1] + a[k];
            ++tot;
        }
        sort(z + 1, z + tot + 1);
        rep(j, t + 1, tot)
            d[i][j - t] = z[j];
        s[i] = tot - t;
    }       
    f[0][0] = 1;
    rep(i, 1, n)
        rep(j, 0, s[i])
        {
            if (d[i][j] > m)    break;
            rep(k, 0, m - d[i][j])
                if (f[i - 1][k])    f[i][k + d[i][j]] = 1;      
        }
    int ans = 0;
    rep(i, 0, m)
        if (f[n][i])    ans = m - i;    
    printf("%d", ans);
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值