HDU 6092 Rikka with Subset(动态规划 17多校第五场)

来源:互联网 发布:ipad编程软件 idea 编辑:程序博客网 时间:2024/05/27 20:52
  • 题目大意

    A1An的n个数构成一个集合,这个集合有2n个子集,每个子集的所有数相加得到一个和,有一个B数组,Bi表示和为i(1im)的集合有多少个.
    现在输入nmB0...Bm,让你输出A数组(1n50,1m104,0Bi2n)

  • 分析
    我们从一些小的情况开始分析,由题目可知,B0一定是1,B1的值就是1的个数,对于B2,我们知道它的值就是全部由1组成的和为2的集合数加上元素2的个数.

    我们用Ci表示数i的个数,知道i的个数之后我们可以通过在之后的B数组中消掉这个数的影响这样依次的得到每一个Ci

    ​做法是,对于Ci不为0的每一个i,对于i之后的每一个j,做Bj=BjBji

  • 代码

#include<bits/stdc++.h>using namespace std;const int MAXN=100005;long long int n,m;int T=0;int b[MAXN];int ans[MAXN];int cnt;void Work(){    cnt=0;    for(int i=1;i<=m;i++)    {        int t=b[i];        for(int k=1;k<=t;k++)        {            ans[++cnt]=i;            for(int j=i;j<=m;j++)b[j]-=b[j-i];        }    }    for(int i=1;i<cnt;i++) printf("%d ",ans[i]);    printf("%d\n",ans[cnt]);}int main(){    scanf("%d",&T);    while(T--)    {        memset(b,0,sizeof(b));        memset(ans,0,sizeof(ans));        scanf("%d%d",&n,&m);        for(int i=0;i<=m;i++) scanf("%d",&b[i]);       Work();    }}
原创粉丝点击