HDU6092 Rikka with Subset(01背包,2017 HDU多校联赛 第5场)
2017-08-09 11:01
459 查看
题目:
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 972 Accepted Submission(s): 476
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
2017 Multi-University Training Contest - Team 5
Recommend
liuyiding | We have carefully selected several similar problems for you: 6095 6094 6093 6092 6091
Statistic | Submit | Discuss | Note
思路:
有两个数组a[]和b[],每一个b[i]代表在a数组里面一些元素的和加起来等于i的子集的个数。
题目给了一个n代表a数组的个数,给了一个m代表a数组中所有元素的总和
问题:求出a数组,并且输出。
定义dp[i]:当前和为i的子集有多少个
要和b[i]区分一下,b[i]是最终的结果,而dp[i]是当前正在推算的结果。
所以,令 X=b[i]-dp[i],代表了最终状态的子集个数减去当前个数的子集个数,也就是需要添加X个和为i的子集,那么我们直接在a数组里添加X个i,就可以使dp[i]达到b[i]的状态,
然后我们再更新dp[k]的值,也就是dp[k]=dp[k]+dp[k-i]
代码:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define N 300
#define ll long long
using namespace std;
int a[10010],b[10010],dp[10010];
int main()
{
int t,n,m,x;
scanf("%d",&t);
while(t--)
{
mem(dp,0);
scanf("%d%d",&n,&m);
int p=0;
for(int i=0; i<=m; i++)
scanf("%d",&b[i]);
dp[0]=1;
for(int i=1; i<=m; i++)
{
int x=b[i]-dp[i];
for(int j=0; j<x; j++)
{
a[p++]=i;
for(int k=m; k>=i; k--)
dp[k]+=dp[k-i];
}
}
for(int i=0; i<p; i++)
{
if(i)printf(" ");
printf("%d",a[i]);
}
puts("");
}
return 0;
}
Rikka with Subset
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)Total Submission(s): 972 Accepted Submission(s): 476
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
2017 Multi-University Training Contest - Team 5
Recommend
liuyiding | We have carefully selected several similar problems for you: 6095 6094 6093 6092 6091
Statistic | Submit | Discuss | Note
思路:
有两个数组a[]和b[],每一个b[i]代表在a数组里面一些元素的和加起来等于i的子集的个数。
题目给了一个n代表a数组的个数,给了一个m代表a数组中所有元素的总和
问题:求出a数组,并且输出。
定义dp[i]:当前和为i的子集有多少个
要和b[i]区分一下,b[i]是最终的结果,而dp[i]是当前正在推算的结果。
所以,令 X=b[i]-dp[i],代表了最终状态的子集个数减去当前个数的子集个数,也就是需要添加X个和为i的子集,那么我们直接在a数组里添加X个i,就可以使dp[i]达到b[i]的状态,
然后我们再更新dp[k]的值,也就是dp[k]=dp[k]+dp[k-i]
代码:
#include <cstdio>
#include <cstring>
#include <cctype>
#include <string>
#include <set>
#include <iostream>
#include <stack>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f
#define N 300
#define ll long long
using namespace std;
int a[10010],b[10010],dp[10010];
int main()
{
int t,n,m,x;
scanf("%d",&t);
while(t--)
{
mem(dp,0);
scanf("%d%d",&n,&m);
int p=0;
for(int i=0; i<=m; i++)
scanf("%d",&b[i]);
dp[0]=1;
for(int i=1; i<=m; i++)
{
int x=b[i]-dp[i];
for(int j=0; j<x; j++)
{
a[p++]=i;
for(int k=m; k>=i; k--)
dp[k]+=dp[k-i];
}
}
for(int i=0; i<p; i++)
{
if(i)printf(" ");
printf("%d",a[i]);
}
puts("");
}
return 0;
}
相关文章推荐
- HDU6092---Rikka with Subset(2017多校联赛:逆向dp)
- HDU 6092 Rikka with Subset (2017多校5-背包)
- hdu 6092 Rikka with Subset(逆向01背包+思维)
- HDU6095 Rikka with Competition(水题,2017 HDU多校联赛 第5场)
- HDU6092-2017多校5&&背包&贪心-Rikka with Subset
- HDU 6092 Rikka with Subset(01背包 思维)
- hdu 6092 Rikka with Subset(逆向01背包+思维)
- (2017多校训练第五场)HDU - 6092 Rikka with Subset 0-1背包
- HDU 6092 Rikka with Subset(背包+思维)
- HDU 2017 多校联赛2 1001 Is Derek lying?
- HDU6103 Kirinriki(尺取法,2017 HDU多校联赛 第6场)
- HDU 2017多校联赛-Maximum Sequence
- HDU 2017 多校联赛2 1011 Regular polygon
- HDU 2017 多校联赛4 1011 Time To Get Up
- HDU 2017 多校联赛 1001 Add More Zero
- (FFT)HDU 6088(2017 多校第5场 1004)Rikka with Rock-paper-scissors
- HDU6168 Numbers(模拟,2017 HDU多校联赛 第9场)
- 陈老师的多校联合20140811||HDU 3236 ||2009年武汉站G题 01背包问题
- HDU 2017多校联赛-1011 KazaQ's Socks
- HDU 2017多校联赛-1012 Balala Power!