Y的积木

dp

一眼看上去就要统计方案:设dp[i][k]代表考虑到第i行,满足价值总和为k的方案数。
转移挺简单的:\[dp[i][k]=\sum \limits_{j=1}^m dp[i-1][k-j]\]

code:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
#define max(a,b) a>b?a:b
#define maxn 102
using namespace std;
int n,fcnt,fina;
int num[maxn],bkt[maxn][maxn],dp[maxn][maxn*maxn],mx[maxn];
int main()
{
    cin>>n>>fcnt;
    for (int i=1,a,b;i<=n;++i)
    {
        scanf("%d",&a);
        for (int j=1;j<=a;++j)
        {
            scanf("%d",&b);
            bkt[i][b]++;
            mx[i]=max(mx[i],b);
        }
        fina+=mx[i];
    }
    for (int i=1;i<=mx[1];++i) {dp[1][i]=bkt[1][i];} 
    for (int i=2;i<=n;++i)
    {
        for (int j=1;j<=fina;++j)
        for (int k=1;k<=mx[i];++k) 
        if (j-k>0&&bkt[i][k]) dp[i][j]+=dp[i-1][j-k]*bkt[i][k];
    }
    int cnt=0;
    for (int i=1;i<=fina;++i)
    for (int j=1;j<=dp[n][i];++j)
    {
        cnt++;
        if (cnt>fcnt) return 0;
        printf("%d ",i);
    }
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/bullshit/p/9811786.html