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;
}
posted @ 2018-10-18 17:21  Splitor  阅读(166)  评论(0编辑  收藏  举报