Codeforces Round #407 (Div. 2)-E-The Great Mixing-滚动数组或者dfs

来源:互联网 发布:知远防务网站 编辑:程序博客网 时间:2024/05/16 15:41

给定一种浓度的啤酒,给你个数字n,下面是n种浓度的啤酒,让你配成这种浓度的啤酒,问你最少需要多少份原料啤酒。
因为浓度范围很大,1后面6个零,背包就算了。范围太大。
方法1 用bitset实现滚动数组,然后用位运算可以完全模拟配酒的过程(关键在那个或),并且位运算很快,不会超时。
方法2 用BFS,要注意用map来记录他们出现的次数,这个和第一种思路差不多,就是实现方法不太一样,还有就是需要用一个map,
两种写法有异曲同工之妙。
注意充分理解或运算(上一种状态包含所有配酒的一杯的状态,下一状态,加一杯,所有的上一种状态都加上这一个,得到aa,ba,ca,da,并且在这个i中再进行或运算的时候不会丢失,在保留上述四种前提下得到 ab,bb,cb,db,如果撞了只会得到一个,)

#include <bits/stdc++.h>using namespace std;int main(){  int m,n;   int a[10000006];   queue<int>q;   while(!q.empty())    q.pop();   map<int ,int >mp;    scanf("%d%d",&m,&n);   for(int i=0;i<n;i++)    {scanf("%d",&a[i]);     a[i]-=m;    }   sort(a,a+n);    int cnt=unique(a,a+n)-a;//去重。   q.push(0);    while(!q.empty())    {   int u=q.front();        q.pop();        for(int i=0;i<cnt;i++)        {   int y=u+a[i];           if(abs(y)>=1001)             continue;//超量就继续,不用在判断了。           if(y==0)           {   cout<<mp[u]+1<<endl;              return 0;           }            if(!mp[y])//保证他是第一次出现,才加上。不然重复的数太多。            {                mp[y]=mp[u]+1;               q.push(y);            }        }    }    cout<<"-1"<<endl;    return 0;}
#include <bits/stdc++.h>//前几天我误以为我理解了这个代码,后来发现还是没有理解bitset的精髓。/*bitset竟然完美的代替了背包,当l为1是,//他的每一个置1的地方就是一个试剂的容量而当l等于2的时候,会得到各种试剂的两种的配料,自己想想,关键是滚动数组的搞,太会玩了,城里人就是强。*/  using namespace std;  const int maxn=1e6+10;  int n,k;  int a[maxn];  bitset<2010> dp[2];  int main()  {     //freopen("de.txt","r",stdin);     scanf("%d%d",&k,&n);          for(int i=0;i<n;i++)            {scanf("%d",&a[i]);             a[i]-=k;            }            sort(a,a+n);           n=unique(a,a+n)-a;//得到的是位置。           int t=1;           memset(dp,0,sizeof(dp));           dp[1-t][1000]=1;           for(int i=1;i<=1020;i++)           {   for(int j=0;j<n;j++)                {  if(a[j]>0)                     dp[t]|=dp[1-t]<<(a[j]);                    else                      dp[t]|=dp[1-t]>>(-a[j]);                }               if(dp[t][1000]!=0)               {  cout<<i<<endl;                  return 0;               }               t=1-t;               dp[t].reset();           }       printf("-1\n");     return 0; }
2 0