HDU - 6092 Rikka with Subset
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 nn positive A1−AnA1−An and their sum is mm. Then for each subset SS of AA, Yuta calculates the sum of SS.
Now, Yuta has got 2n2n numbers between [0,m][0,m]. For each i∈[0,m]i∈[0,m], he counts the number of iis he got as BiBi.
Yuta shows Rikka the array BiBi and he wants Rikka to restore A1−AnA1−An.
It is too difficult for Rikka. Can you help her?
Input
The first line contains a number t(1≤t≤70)t(1≤t≤
Sample Input
2 2 3 1 1 1 1 3 3 1 3 3 170), the number of the testcases.
For each testcase, the first line contains two numbers n,m(1≤n≤50,1≤m≤104)n,m(1≤n≤50,1≤m≤104).
The second line contains m+1m+1 numbers B0−Bm(0≤Bi≤2n)B0−Bm(0≤Bi≤2n).
Output
For each testcase, print a single line with nn numbers A1−AnA1−An.
It is guaranteed that there exists at least one solution. And if there are different solutions, print the lexicographic minimum one.
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]$
题目大意:一个集合A中有n个元素,集合A中所有的元素和为m,求出集合A所有子集的和,集合B中元素b[i]表示集合A的子集中所有和为i 的个数,给出集合B求出集合A
解题思路:逆向dp,我们设dp[i]表示集合A的子集中和为i的个数,则可以这样求出dp[i]
for(int i=1;i<=n;i++)
{
for(int j=m;j>=a[i];j--)
dp[j]+=dp[j-a[i]];
}
根据求dp[i]的方法可以逆向dp来求a[i],我们需要找出集合A的第一个元素从1开始从前往后找,那么第一个b[i]不等于0的i一定是集合A中的最小的那个元素,因为b[i]是集合A的子集中和为i的个数,集合A中最小的那个元素单独一个子集和最小,这时就很容易找到所有集合A的元素,然后逆向dp,每次都把最小的元素加进去,这样最后输出的就是字典序最小的集合A
AC代码
#include<iostream>
#include<cstdio>
using namespace std;
const int maxn=1e4+10;
typedef long long LL;
LL dp[maxn],b[maxn];
int a[55];
int main()
{
int t,n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d%d",&n,&m);
for(int i=0;i<=m;i++)
scanf("%lld",&b[i]);
for(int i=1;i<=m;i++)
{
if(b[i])
{
a[1]=i;//找集合A最小的那个元素
break;
}
}
int cnt=2;
for(int i=1;i<=n;i++)////从第一个数反过来DP
{
for(int j=a[i],flag=0;j<=m;j++)
{
b[j]-=b[j-a[i]];//去掉A的第i和元素时和为j的个数
if(b[j]>0&&flag==0)
{
a[cnt++]=j;///每次都要把最小的j且b[j]!=0的数加入a中
flag=1;
}
}
}
for(int i=1;i<=n;i++)
{
if(i==n)
printf("%d\n",a[i]);
else
printf("%d ",a[i]);
}
}
return 0;
}
- HDUOJ-----Computer Transformation
- Veeam Backup & Replication(二):添加虚拟化主机和配置备份存储
- HDUOJ 2672---god is a girl 《斐波那契数》
- Golang语言--一些基础用法
- 复杂SQL性能优化的剖析(一)(r11笔记第36天)
- hduoj1073--Online Judge
- Golang语言--- channel
- Golang语言--将byte的int转换
- HDUOJ------Daydream字符查找-并求其始末位置
- HDUOJ------敌兵布阵
- 复杂SQL性能优化的剖析(二)(r11笔记第37天)
- HDUOJ-------Being a Good Boy in Spring Festival
- Golang语言--slice 切片原理
- GoLang语言--的函数运用
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- JavaScript 技巧篇-js增加延迟时间解决单击双击事件冲突,双击事件触发单击事件
- Python 技术篇-sha256()加密的使用方法,sha1、md5加密方法
- Python 技术篇-如何打印一段文字,用友云霸气控制台颜文字打印
- Python 技术篇-获取秒级时间戳、毫秒级时间戳
- Python 技术篇-基于随机数的uuid码的生成
- BAT 脚本技术-利用bat批处理脚本静态指定ip地址、自动获取ip地址设置
- Oracle 技巧篇-快速批量删除当前数据库连接的用户,一键清空所有session会话方法
- Spring Security 中如何细化权限粒度?
- 小书MybatisPlus第4篇-表格分页与下拉分页查询
- 小书MybatisPlus第3篇-自定义SQL
- Nginx + Spring Boot 实现负载均衡
- 小书MybatisPlus第2篇-条件构造器的应用及总结
- 一个案例演示 Spring Security 中粒度超细的权限控制!
- 信息收集之主机发现:nmap
- 文本文件逐行处理–用java8 Stream流的方式