zoukankan      html  css  js  c++  java
  • C

    C - Thief in a Shop

     思路 :严格的控制好k的这个数量,这就是个裸完全背包问题.(复杂度最极端会到1e9)

    他们随意原来随意组合的方案,与他们都减去 最小的 一个 a[ i ] 组合的方案数目是不会改变的

    那么我们就 dp [ i ]表示 i 这个价格需要的最少 个数。  这样求最小个数保证不会漏解

    然后 如果这个  i 能通过 1 - k 个物品组合出来,那么 一定能通过k 个物品组合出 i + k * a [ 1 ].

    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    #define inf 0x3f3f3f3f
    #define maxn 1234567
    int n,k,dp[maxn],a[maxn];
    int v[maxn],mi,sum,id,base;
    map<int,bool>vis;
    vector<int>ans;
    int main()
    {
        scanf("%d%d",&n,&k);
        for(int i=1; i<=n; i++)
        {
            scanf("%d",&a[i]);
            if(vis[a[i]]==0)
            {
                vis[a[i]]=1;
                v[++id]=a[i];
            }
        }
        sort(v+1,v+1+id);
        base=v[1]*k;
        for(int i=2; i<=id; i++)
            v[i]-=v[1];
        sum=v[id]*k;
        memset(dp,inf,sizeof(dp));
        dp[0]=0;
        for(int i=2; i<=id; i++)
            for(int j=v[i]; j<=sum; j++)
                dp[j]=min(dp[j],dp[j-v[i]]+1);
        for(int i=0; i<=sum; i++)
        {
            if(dp[i]>k)continue;
                ans.push_back(i+base);
        }
        int len=ans.size();
        for(int i=0; i<len; i++)
        {
            printf("%d",ans[i]);
            if(i<len-1)printf(" ");
            else printf("
    ");
        }
        return 0;
    }
    

      思路:最初有的ai 初始化系数为1进行操作k次卷积。注意补零操作,然后注意最大长度,

    也就是最终结果可能得到的最大指数 ....

    #include <stdio.h>
    #include <string.h>
    #include <iostream>
    #include <algorithm>
    #include <math.h>
    #include <cstring>
    #include <cmath>
    using namespace std;
    const double PI = acos(-1.0);
    struct complex
    {
        double r,i;
        complex(double _r = 0.0,double _i = 0.0)
        {
            r = _r;
            i = _i;
        }
        complex operator +(const complex &b)
        {
            return complex(r+b.r,i+b.i);
        }
        complex operator -(const complex &b)
        {
            return complex(r-b.r,i-b.i);
        }
        complex operator *(const complex &b)
        {
            return complex(r*b.r-i*b.i,r*b.i+i*b.r);
        }
    };
    void change(complex y[],int len)
    {
        int i,j,k;
        for(i = 1, j = len/2; i < len-1; i++)
        {
            if(i < j)swap(y[i],y[j]);
            k = len/2;
            while( j >= k)
            {
                j -= k;
                k /= 2;
            }
            if(j < k) j += k;
        }
    }
    void fft(complex y[],int len,int on)
    {
        change(y,len);
        for(int h = 2; h <= len; h <<= 1)
        {
            complex wn(cos(-on*2*PI/h),sin(-on*2*PI/h));
            for(int j = 0; j < len; j+=h)
            {
                complex w(1,0);
                for(int k = j; k < j+h/2; k++)
                {
                    complex u = y[k];
                    complex t = w*y[k+h/2];
                    y[k] = u+t;
                    y[k+h/2] = u-t;
                    w = w*wn;
                }
            }
        }
        if(on == -1)
            for(int i = 0; i < len; i++)
                y[i].r /= len;
    }
    const int MAXN = 5234567;
    complex x1[MAXN],x2[MAXN];
    char str1[MAXN/2],str2[MAXN/2];
    int sum[MAXN];
    int siz[1100];
    int main()
    {
        int n,k;
        scanf("%d %d", &n, &k);
        int x;
        int MAX = 0;
        memset(siz,0,sizeof(siz));
        for(int i = 1; i <= n; i++)
        {
            scanf("%d", &x);
            siz[x] = 1;
            MAX = max(MAX,x);
        }
        int len1 = MAX * k;
        int len = 1;
        while(len < len1) len <<= 1;
        for(int i = 0; i < len; i++)
            x1[i] = complex(siz[i],0);
        x2[0] = complex(1,0);
        for(int i=1; i < len; i++)
            x2[i] = complex(0,0);
        fft(x1,len,1);
        fft(x2,len,1);
        while(k)
        {
            if(k % 2 == 1)
            {
                for(int i = 0; i <len; i++)
                    x2[i] = x1[i]*x2[i];
                fft(x2,len,-1);
                for(int i = 0; i < len; i++)
                {
                    sum[i] = (int)(x2[i].r + 0.5);
                    if(sum[i])x2[i]=complex(1,0);
                    else x2[i]=complex(0,0);
                }
                fft(x2,len,1);
            }
            for(int i =0; i < len; i++)
                x1[i] = x1[i]*x1[i];
            fft(x1,len,-1);
            for(int i = 0; i < len; i++)
            {
                sum[i] = (int)(x1[i].r + 0.5);
                if(sum[i])x1[i]=complex(1,0);
                else x1[i]=complex(0,0);
            }
            fft(x1,len,1);
            k /= 2;
        }
        fft(x2,len,-1);
        for(int i = 0; i < len; i++)
        {
            sum[i] = (int)(x2[i].r + 0.5);
        }
        for(int i = 0; i <len; i++)
        {
            if(sum[i])
                printf("%d ",i);
        }
        return 0;
    }
    

      

  • 相关阅读:
    HDU1260DP
    HDU1114 背包
    HDU1078记忆化搜索
    HDU1024 最大m子段和
    Codeforces Round #401 (Div. 2) A,B,C,D,E
    HDU3666 差分约束
    HDU1540 区间合并
    HDU3308 线段树(区间合并)
    Codeforces Round #403 (Div. 2) B 三分 C dfs
    HDU1573 线性同余方程(解的个数)
  • 原文地址:https://www.cnblogs.com/SDUTNING/p/10310885.html
Copyright © 2011-2022 走看看