博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU 6092 Rikka with Subset 【dp多重背包】【好题】
阅读量:6901 次
发布时间:2019-06-27

本文共 2743 字,大约阅读时间需要 9 分钟。

Rikka with Subset

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 139    Accepted Submission(s): 49
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 
A1An 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 
A1An.
It is too difficult for Rikka. Can you help her?  
 
Input
The first line contains a number 
t(1t70), the number of the testcases. 
For each testcase, the first line contains two numbers 
n,m(1n50,1m104).
The second line contains 
m+1 numbers 
B0Bm(0Bi2n).
 
Output
For each testcase, print a single line with 
n numbers 
A1An.
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

题意:有一个数列 a[] ,长度(n<=50)。b[i] 表示元素和为 i 的集合个数。给你一个数列 b[] ,长度(m<=10000),让你求 a[],并按照其字典序最小输出

显然数字0的数量num[0]为log2(b[0]),数字1的数量num[1]为b[1]/b[0]

设dp[i],表示在当前i没有的情况下,用前面已知数量的数组成数字i共有多少种情况

那么b[i]-dp[i]即为数字i与0进行组合的可能性,则num[i]=(b[i]-dp[i])/b[0]

这里如果直接写的话复杂度为o(m^2)会超时,所以需要剪枝:

if (dp[j] == 0) continue;if (num[i] == 0) break;
直接将m^2的复杂度降为nm

#include 
#include
#include
#include
#include
#include
#include
#define ms(a,b) memset(a,b,sizeof(a)) using namespace std;typedef long long ll;const int maxn = 1e4 + 100;ll b[maxn];int dp[maxn], num[maxn];int C(int n, int m){ int sum = 1; for (int i = n - m + 1; i <= n; i++) sum *= i; for (int i = 1; i <= m; i++) sum /= i; return sum;}int main(){ int t; scanf("%d", &t); while (t--) { int n, m; scanf("%d%d", &n, &m); ms(dp, 0); ms(num, 0); for (int i = 0; i <= m; i++) { scanf("%lld", &b[i]); } num[0] = log2(b[0]); num[1] = b[1] / b[0]; dp[0] = b[0]; for (int i = 0; i <= m; i++) { for (int j = m; j >= 0; j--) { if (dp[j] == 0) continue; if (num[i] == 0) break; for (int k = 1; k <= num[i]; k++) { if (j + k*i <= m) { dp[j + k*i] += dp[j] * C(num[i], k); } } } if (i + 1 <= m) { num[i + 1] = (b[i + 1] - dp[i + 1]) / b[0]; } } bool flag = 0; for (int i = 0; i <= m; i++) { for (int j = 1; j <= num[i]; j++) { if (!flag) printf("%d", i), flag = 1; else printf(" %d", i); } } puts(""); } return 0;}

转载于:https://www.cnblogs.com/Archger/p/8451604.html

你可能感兴趣的文章
redis python监控
查看>>
php趣味 - php 奥运五环
查看>>
Ext4 Disk Layout-2
查看>>
原 2017/5 JavaScript基础6--- 对象
查看>>
Python 列表、元组、字典t的常用方法
查看>>
MYSQL groupby使用方法。
查看>>
如何将ppt转换成pdf
查看>>
PowerDesigner连接MySQL数据库
查看>>
文件格式转换控件LEADTOOLS ePrint Professional
查看>>
ORACLE常见的六种RMAN恢复测试
查看>>
(Portal 开发读书笔记) Personalization
查看>>
SRCNN 实验细节
查看>>
Java多线程第二节-线程的基本使用
查看>>
界面控件Essential Studio for ASP.NET Web Forms 2017 v3发布丨附下载
查看>>
教你制作属于自己的CentOS 6.4一键自动化安装ISO镜像光盘
查看>>
线上 mysql 主库配置文档
查看>>
Java web部署目录结构和web.xml作用
查看>>
负载均衡DR(direct routing)模式
查看>>
Python中list的遍历
查看>>
Linux下查看内存等硬件信息
查看>>