您的位置:首页 > 其它

【2017多校】HDU6092 Rikka with Subset 【DP】

2017-08-08 20:03 393 查看
传送门

令xi=sum和为i,且不包含>=i的数的集合的数量

则numi=A[1...n]中等于i的数个数=Bi−xi

于是,m为背包大小,numi为物品个数,每个物品体积=i,dpj=体积为j时方案数,求背包即可

又因为∑numi<=50,所以复杂度为O(n∗m)

#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<stdlib.h>
#include<string.h>
#include<vector>
#include<queue>
//#include<bits/stdc++.h>
#define ll long long
#define pii pair<int,int>
#define pll pair<ll,ll>
#define MEM(a,x) memset(a,x,sizeof(a))
#define lowbit(x) ((x)&-(x))

using namespace std;

const int N = 1e4 +5;

ll b
;
ll x
;
int num
;

void printAns(int n,int m){
int cnt=0;
for(int i=0;i<=m;++i){
for(int j=0;j<num[i];++j){
++cnt;
printf("%d%c",i,cnt==n?'\n':' ');
}
}
}

void dp(int m){
fill(x,x+m+1,0);
x[0]=1;
for(int i=1;i<=m;++i){
num[i]=b[i]-x[i];
for(int j=1;j<=num[i];++j){
for(int k=m;k>=i;--k){
x[k]+=x[k-i];
}
}
}
}

int main()
{
//freopen("/home/lu/code/r.txt","r",stdin);
//freopen("/home/lu/code/w.txt","w",stdout);
int T;
scanf("%d",&T);
while(T--){
int n,m;
scanf("%d%d",&n,&m);
for(int i=0;i<=m;++i){
scanf("%lld",&b[i]);
}
dp(m);
printAns(n,m);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  DP 2017多校