Rikka with Subset

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)

Total Submission(s): 1440    Accepted Submission(s): 721


Problem Description
As we know, Rikka is poor at math. Yuta is worrying about this situation, so he gives Rikka some math tasks to practice. There is one of them:

Yuta has n positive A1−An and
their sum is m.
Then for each subset S of A,
Yuta calculates the sum of S. 

Now, Yuta has got 2n numbers
between [0,m].
For each i∈[0,m],
he counts the number of is
he got as Bi.

Yuta shows Rikka the array Bi and
he wants Rikka to restore A1−An.

It is too difficult for Rikka. Can you help her?  
 

Input
The first line contains a number t(1≤t≤70),
the number of the testcases. 

For each testcase, the first line contains two numbers n,m(1≤n≤50,1≤m≤104).

The second line contains m+1 numbers B0−Bm(0≤Bi≤2n).
 

Output
For each testcase, print a single line with n numbers A1−An.

It is guaranteed that there exists at least one solution. And if there are different solutions, print the lexicographic minimum one.
 

Sample Input

2
2 3
1 1 1 1
3 3
1 3 3 1
 

Sample Output

1 2
1 1 1

Hint

In the first sample, $A$ is $[1,2]$. $A$ has four subsets $[],[1],[2],[1,2]$ and the sums of each subset are $0,1,2,3$. So $B=[1,1,1,1]$

 

Source
 

Recommend
liuyiding   |   We have carefully selected several similar problems for you:  6095 6094 6093 6092 6091 
 

Statistic | Submit | Discuss | Note

思路:动态规划+思维

因为已知了集合B要求集合A的序列,显然空集与全集的数量都为1,所以B0和Bm都为1

集合A中1的数量就等于B1,那么B2便可以由B1推出(排列组合的思想),B3可有B2推出,以此类推,采用01背包为题解决

#include <iostream>
#include<algorithm>
#include<string.h>
#include<stdint.h>
using namespace std;
const int maxn=10005; int a[maxn],b[maxn],c[maxn],dp[maxn];
//dp[i]表示:加和为i的子集个数 int main()
{
int t;
scanf("%d",&t);
int n,m;
while(t--)
{
scanf("%d%d",&n,&m);
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
memset(dp,0,sizeof(dp)); dp[0]=1;
for(int i=0;i<=m;i++)
{
scanf("%d",&b[i]);
}
int p=0,sum=0;
for(int i=1;i<=m;i++)
{
c[i]=b[i]-dp[i];//A序列中值为i的个数
for(int j=0;j<c[i];j++)
{
a[p++]=i;//对A序列赋值
for(int k=m;k>=i;k--)
{//处理成01背包问题
dp[k]+=dp[k-i];//和为k的子集个数相加去更新B序列 }
} }
for(int i=0;i<p-1;i++)
{
printf("%d ",a[i]); }
printf("%d\n",a[p-1]);
}
return 0;
}

最新文章

  1. Oracle Blob 字段的模糊查询
  2. u-boot board_uart_init流程
  3. jquery Ajax应用总结
  4. java工作流bpm开发ERP实例
  5. map,zip,reduce函数
  6. spring boot MySQL极简封装
  7. socket(套接字)初使用
  8. bootstrap table表格前台分页,点击tab选项,重新刷新表格
  9. 【Java并发编程】21、线程池ThreadPoolExecutor源码解析
  10. GitHub安装教程
  11. sscanf的字符串格式化用法
  12. pandas apply()函数参数 args
  13. 浏览器实现PDF预览
  14. Prometheus Node_exporter 之 Network Traffic Detail
  15. iOS 项目一直在后台执行
  16. 使用sphinx创建和查看文档
  17. NS3 fifth.cc 拥塞窗口实例
  18. linux命令新建文件
  19. 说一说activity
  20. streamsets 包管理

热门文章

  1. 51nod - 1278 相离的圆 (二分)
  2. &lt;项目&gt;&lt;day11&gt;查看用户浏览过的商品
  3. HashMap源码分析1:添加元素
  4. PC_excel完毕一列英文小写变大写
  5. 加入收藏BUG改善
  6. 状压DP问题
  7. 抢占式内核与非抢占式内核中的自旋锁(spinlock)的差别
  8. muduo源代码分析--Reactor模式在muduo中的使用
  9. SpringMVC学习指南-Spring框架
  10. beego3---gohttp底层实现