2017 Multi-University Training Contest

来源:互联网 发布:销售软件定制 编辑:程序博客网 时间:2024/05/13 09:04

题目链接

原文链接


贴个代码:

#include <iostream>#include <stdio.h>#include <string.h>using namespace std;const int maxn = 1e5;int a[maxn];int b[maxn];int dp[maxn];int main(){    int t,n,m;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        memset(dp,0,sizeof(dp));        for(int i = 0; i <= m; i++)            scanf("%d",&b[i]);        int cnt = 0;        dp[0] = 1;      ///dp[i]代表当前和为i的子集有多少个        for(int i = 0; i < m; i++)        {            int rest = b[i]-dp[i];            ///dp[i]代表当前的a序列中子集和为dp[i]的个数。b[i]-dp[i]就是a序列中还要添加几个数字i            for(int j = 1; j <= rest; j++)            {                a[cnt++] = i;     ///每添加一个i                for(int k = m; k >= i; k--)  ///k-i这个数+i能构成k。                    dp[k] += dp[k-i];            }        }        printf("%d",a[0]);        for(int i = 1; i < cnt; i++)        {            printf(" %d",a[i]);        }        printf("\n");    }    return 0;}