CF 632E Thief in a Shop

来源:互联网 发布:怎样取个淘宝店名 编辑:程序博客网 时间:2024/05/29 04:26

题目大意

n(1000)种物品,数量无限,价值vali[1,1000],输出选取k(1000)个可以得到的所有不同总价值。
构造0然后dp。

#include<cmath>#include<queue>#include<stack>#include<cstdio>#include<bitset>#include<cstring>#include<complex>#include<iostream>#include<algorithm>#define pi acos(-1)#define inf (1<<30)#define INF (1<<62)#define CLR(x,f) memset(x,f,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define prt(x) cout<<#x<<": "<<x<<endl#define huh(x) printf("--------DEBUG(%d)--------\n",x)//#define TLusing namespace std;const int M=1005;int dp[M*M];int val[M],sum=0;int main(){#ifdef TL#endif    int n,K;    scanf("%d%d",&n,&K);    int mi=inf,sum=0,mx=0;    for(int i=1;i<=n;i++){        scanf("%d",&val[i]);        mi=min(mi,val[i]);    }    for(int i=1;i<=n;i++){        val[i]-=mi;        mx=max(val[i],mx);    }    sum=mx*K;    memset(dp,63,sum+1<<2);    dp[0]=0;    for(int i=1;i<=n;i++)        for(int j=val[i];j<=sum;j++)            dp[j]=min(dp[j],dp[j-val[i]]+1);    for(int i=0;i<=sum;i++)        if(dp[i]<=K)printf("%d ",i+mi*K);    return 0;}

或者FFT:p

#include<cmath>#include<queue>#include<stack>#include<ctime>#include<cstdio>#include<bitset>#include<cstring>#include<complex>#include<iostream>#include<algorithm>#define inf (1<<30)#define INF (1<<62)#define y1 safjaklsfasj#define y2 gdfgmsdklg#define tm fjansgfkm#define CLR(x,f) memset(x,f,sizeof(x))#define CPY(x,y) memcpy(x,y,sizeof(x))#define prt(x) cout<<#x<<": "<<x<<endl#define huh(x) printf("--------DEBUG(%d)--------\n",x)//#define TLusing namespace std;typedef long long ll;typedef double doub;typedef long double ld;const ld pi=acos(-1);const int M=2097152;struct comp{    ld real,imag;//double?    comp(){}    comp(ld real_,ld imag_){        real=real_;imag=imag_;    }    friend comp operator+(comp a,comp b){        return comp(a.real+b.real,a.imag+b.imag);    }    friend comp operator*(comp a,comp b){        return comp(a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real);    }    friend comp operator-(comp a,comp b){        return comp(a.real-b.real,a.imag-b.imag);    }}ffa[M],ffb[M],wm[M];int rev[M];void fft(comp *a,int n,int f){    for(int i=0;i<n;i++)if(rev[i]>i)swap(a[rev[i]],a[i]);    for(int m=1;m<n;m<<=1){        comp wi(cos(pi/m),f*sin(pi/m));        wm[0]=comp(1,0);        for(int j=1;j<m;j++)wm[j]=wm[j-1]*wi;        for(int j=0;j<n;j+=(m<<1)){            for(int k=0;k<m;k++){                comp x=a[j+k],y=wm[k]*a[j+k+m];                a[j+k]=x+y;a[j+k+m]=x-y;            }        }    }    if(f==-1)for(int i=0;i<n;i++)a[i].real/=n,a[i].imag/=n;}void mulpoly(int a[],int b[],int c[],int na,int nb,int &n){    int m=max(na,nb)<<1,l=0;    for(n=1;n<m;n<<=1)l++;    for(int i=1;i<n;i++)rev[i]=(rev[i>>1]>>1)|((i&1)<<l-1);    for(int i=0;i<n;i++)ffa[i]=ffb[i]=comp(0,0);    for(int i=0;i<na;i++)ffa[i]=comp(a[i],0);    for(int i=0;i<nb;i++)ffb[i]=comp(b[i],0);    fft(ffa,n,1);fft(ffb,n,1);    for(int i=0;i<n;i++)ffa[i]=ffa[i]*ffb[i];    fft(ffa,n,-1);    for(int i=0;i<n;i++)c[i]=(int)(ffa[i].real+0.5);}int a[M],b[M],c[M];int main(){#ifdef TL    freopen("data.in","r",stdin);    freopen("data.out","w",stdout);#endif    int n,k,nb=0,na=1;    scanf("%d%d",&n,&k);    for(int v,i=1;i<=n;i++){        scanf("%d",&v);        b[v]=1;        nb=max(nb,v);    }++nb;    a[0]=1;    for(;k;k>>=1){        if(k&1){            mulpoly(a,b,c,na,nb,n);            na+=nb-1;            for(int i=0;i<na;i++)                a[i]=(c[i]>0);        }        mulpoly(b,b,c,nb,nb,n);        nb+=nb-1;        for(int i=0;i<nb;i++)b[i]=(c[i]>0);    }    for(int i=0;i<na;i++)        if(a[i])printf("%d ",i);    return 0;}
0 0
原创粉丝点击