大水题..先介绍下第一种做法dp观察数据易知..每个数大概就是0~100之间,然后最多100组,所以建立一个dp数组dp[i][j]表示到第i组,价值为j的数量是多少?
然后转移就更简单了,思想就是桶,你这个转态肯定是有上一个转态+a[i][j]组成a[i][j]表示第i组位于j的价值..然后注意把第一组初始化为1..
所以转移方程就是:

dp[i][k+a[i][j]]+=dp[i-1][k];

最后从1开始找到10000找k个数就好了..时间复杂度大概1e8吧..
AC代码

#include<bits/stdc++.h>
#define ios ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define pb push_back
#define inf 132913423039
typedef long long ll;
const ll mod=1e9+7;
const ll N=1e5+5;
const int max_=1e5+5;
const double eps=1e-7;
using namespace std;
ll gcd(ll a,ll b) {return b==0?a:gcd(b,a%b);}
ll lcm(ll a,ll b) { return a*b/gcd(a,b);    }
ll qp(ll a,ll b, ll p){ll ans = 1;while(b){if(b&1){ans = (ans*a)%p;--b;}a = (a*a)%p;b >>= 1;}return ans%p;}
ll Inv(ll x)          { return qp(x,mod-2,mod);}
ll C(ll n,ll m){if (m>n) return 0;ll ans = 1;for (int i = 1; i <= m; ++i) ans=ans*Inv(i)%mod*(n-i+1)%mod;return ans%mod;}
ll dp[105][105*105];//dp[i][j]到第i组,价值为j的数量是多少?
ll a[105][105];
ll cnt[105];
int main()
{
    ios;
    ll n,m,ans=0;
    cin>>n>>m;
    for(ll i=1;i<=n;i++)
    {
        cin>>cnt[i];
        for(ll j=1;j<=cnt[i];j++) cin>>a[i][j];
    }
    for(ll i=1;i<=cnt[1];i++) dp[1][a[1][i]]=1;//赋初值
    for(ll i=2;i<=n;i++)//3个for复杂度大概1e8吧
    {
        for(ll j=1;j<=cnt[i];j++)
        {
             for(ll k=1;k<=10000;k++)
             {
                 if(k+a[i][j]<=10000)//选了就+ai嘛
                 {
                     dp[i][k+a[i][j]]+=dp[i-1][k];
                 }
             }
        }
    }
    for(;m;)//挑选前m小的数嘛~
    {
        for(ll i=1;i<=10000;i++)
        {
            if(dp[n][i])
            {
                if(m-dp[n][i]>=0) m-=dp[n][i],ans+=dp[n][i]*i;
                else              ans+=m*i,m=0;
            }
            if(m==0) break;
        }
    }
    cout<<ans<<endl;
    return 0;
}

2.dp可以优化的..但是这是思路最简单的一种了