hdu 6092 Rikka with Subset(思路)

来源:互联网 发布:福克斯st轮毂数据 编辑:程序博客网 时间:2024/05/17 01:14

Rikka with Subset

题目链接:Rikka with Subset

题意:有两个数列a[]和b[],b[]表示a[]中元素和为i的集合的个数。给出所有的b[],让你求字典序最小的a[]

思路:如果 b[i]b[] 数组中除了 b[0]以外第一个值不为0的位置,那么显然 i就是 a[]中的最小数。这样最小的数就找到了

又因为较大的数肯定是由许多较小的数合成的,因此我们每寻找到一个a[],都从小到大遍历一遍b[],让b[j]=b[ji]

这样对于每个i,如果b[i]!=0,那它肯定是a[]中的一员

官方题解:
这里写图片描述

代码:

#include<bits/stdc++.h>using namespace std;const int maxn=1e4+10;int a[55],b[maxn];int n,m;int main(){    int t;    scanf("%d",&t);    while(t--)    {        scanf("%d%d",&n,&m);        for(int i=0;i<=m;++i)            scanf("%d",&b[i]);        int ps=0;        for(int i=1;i<=m;++i)        {            if(ps>=n)                break;            if(!b[i])                continue;            a[++ps]=i;            for(int j=i;j<=m;++j)                b[j]-=b[j-i];            --i;        }        for(int i=1;i<ps;++i)            printf("%d ",a[i]);        printf("%d\n",a[ps]);    }    return 0;}

参考博客:
我的程序跑快快



还有一种方法,用dp[i]来记录在i的前面有多少种可以组合成i的方案,那么b[i]-dp[i]就是a[]数组中i的个数了

代码:

#include<bits/stdc++.h>using namespace std;const int maxn=1e4+10;int a[55],b[maxn],dp[maxn];int n,m;int main(){    int t;    scanf("%d",&t);    while(t--)    {        memset(dp,0,sizeof(dp));        scanf("%d%d",&n,&m);        for(int i=0;i<=m;++i)            scanf("%d",&b[i]);        dp[0]=1;        int ps=0;        for(int i=1;i<=m;++i)        {            if(ps>=n)                break;            int k=b[i]-dp[i];            for(int j=0;j<k;++j)            {                a[++ps]=i;                for(int l=m;l>=i;--l)                    dp[l]+=dp[l-i];            }        }        for(int i=1;i<ps;++i)            printf("%d ",a[i]);        printf("%d\n",a[ps]);    }    return 0;}

参考博客:
王小二

原创粉丝点击