HDU6092---Rikka with Subset(2017多校联赛:逆向dp)

来源:互联网 发布:数据流程图符号含义 编辑:程序博客网 时间:2024/05/01 21:02

题目来源:http://acm.hdu.edu.cn/.php?pid=6092

题意

给出a,b俩数组,其中a数组有n项,b[i]是a数组的子集的和为i的个数,现给出b数组,要求求出a数组。

思路

逆向去考虑这个问题,比如给出b数组: 4 6 4 1 0 6 。
那么该如何求出a数组
首先考虑4,那么有四个1在a数组中,然后四个1可以得到6个2,4个3,以及一个4,那么对于b[2]来说刚好,b[3],b[4]同理,然后是b[6]==1,那么a数组里一定有一个6,为啥不是4个1和一个2呢?因为如果a数组里有2的话,那么b[2]就不会是4了,而是5了。。然后反着去考虑。。。

代码

#include<cmath>#include<queue>#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int INF=0x3f3f3f3f;typedef long long LL;const double eps=1e-6;const int N=10000+10;LL a[N],b[N],dp[N];int main(){    int T;    scanf("%d",&T);    while(T--)    {        memset(dp,0,sizeof(dp));        int n,m;        scanf("%d%d",&n,&m);        for(int i=0; i<=m; i++)        {            scanf("%lld",&b[i]);        }        int k=0;dp[0]=1;        for(int i=1;i<=m;i++)        {            int res=b[i]-dp[i];            while(res--)            {                a[++k]=i;                for(int j=m;j>=i;j--)                {                    dp[j]+=dp[j-i];                }            }        }        printf("%lld",a[1]);        for(int i=2;i<=n;i++)        {            printf(" %lld",a[i]);        }        printf("\n");    }}
原创粉丝点击