【洛谷 P2409】Y的积木(dp(01背包))
【题解】【01背包】
【考试的时候类比到两列数每列取一个求前k个最小值,然后,就按那个做了n-1次。然后,搞成一坨。。。】
【后来发现,其实只是一个dp。用f[i][j]表示加到第i行,此时总和为j的情况。然后逐层按01背包处理即可】
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int f[110][10010];
int a[110][110],m[110],n,k,sumx,summ;
int main()
{
freopen("int.txt","r",stdin);
freopen("my.txt","w",stdout);
int i,j;
memset(f,0,sizeof(f));
scanf("%d%d",&n,&k);
for(i=1;i<=n;++i)
{
int maxn=0,minn=0x7fffffff;
scanf("%d",&m[i]);
for(j=1;j<=m[i];++j)
{
scanf("%d",&a[i][j]);
if(a[i][j]>maxn) maxn=a[i][j];
if(a[i][j]<minn) minn=a[i][j];
}
sumx+=maxn;
}
f[0][0]=1;
for(i=1;i<=n;++i)
for(j=1;j<=m[i];++j)
for(int h=sumx;h>=a[i][j];h--)
if(f[i-1][h-a[i][j]])
f[i][h]+=f[i-1][h-a[i][j]];
for(i=1;i<=sumx;++i)
if(k)
for(j=1;j<=f[n][i];++j)
if(k) printf("%d ",i),k--;
else return 0;
else return 0;
}
既然无能更改,又何必枉自寻烦忧