C - Thief in a Shop - dp完全背包-FFT生成函数

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("\n");
    }
    return 0;
}

  

猜你喜欢

转载自www.cnblogs.com/SDUTNING/p/10310885.html
今日推荐