• Codeforces 788C The Great Mixing(背包问题建模+bitset优化或BFS)


    【题目链接】 http://codeforces.com/problemset/problem/788/C

    【题目大意】

      给出一些浓度的饮料,要求调出n/1000浓度的饮料,问最少需要多少升饮料

    【题解】

      设浓度为a,现在要求出系数x1,x2,x3……,使得x1*a1+x2*a2+x3*a3+……=n*(x1+x2+x3+……)
      得a1*(x1-n)+a2*(x2-n)+a3*(x3-n)+……=0
      假设现在有x1-n和x2-n,设其数值为x和y,那么一定有(x)*y+(-y)*x=0,
      x+y=x-(-y)<1000,更多物品的答案不会超过两个物品,所以答案最多1000,
      那么现在就是背包问题容量0是否能被覆盖到,因为状态只有两种,是否被覆盖,
      所以我们可以用bitset优化。

      同时,我们发现这个最小答案相当于求最短路的过程,每次可以有一定的步长,
      问到达目标状态的最小值,所以可以将每种物品作为步长,用bfs来解决背包问题。

    【代码】

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <bitset>
    #include <vector>
    using namespace std;
    typedef long long LL;
    int x,n,k;
    int main(){
    	  scanf("%d%d",&n,&k);
    	  vector<bool> vis(1001,0);
    	  for(int i=1;i<=k;i++){
    	      scanf("%d",&x);
    	      vis[x]=1;
    	  }vector<int> v;
    	  for(int i=0;i<=1000;i++)if(vis[i])v.push_back(i-n);
    	  bool flag=0;
    	  bitset<2010>cur,nxt;
    	  cur[1000]=1;
    	  for(int i=1;i<=1000&&!flag;i++){
    	      nxt.reset();
    	      for(int x=0;x<v.size();x++){
    	          if(v[x]>0)nxt|=cur<<v[x];
    	          else nxt|=cur>>-v[x];
    	      }swap(cur,nxt);
    	      if(cur[1000]){flag=1;printf("%d
    ",i);}
    	  }if(!flag)puts("-1");
        return 0;
    }
    
    #include <cstdio>
    #include <vector>
    #include <queue>
    using namespace std;
    int n,k,x;
    int main(){
        scanf("%d%d",&n,&k);
        vector<bool> vis(1001,0);
        for(int i=1;i<=k;i++){
            scanf("%d",&x);
            vis[x]=1;
        }vector<int> vs;
        for(int i=0;i<=1000;i++)if(vis[i])vs.push_back(i-n);
        vector<int> dp(2010,-1),q;
        for(int i=0;i<vs.size();i++){
            int u=vs[i]+1000;
            dp[u]=1;
            q.push_back(u);
        }
        for(int i=0;i<q.size();i++){
            int u=q[i];
            for(int x=0;x<vs.size();x++){
                int v=u+vs[x];
                if(v>=0&&v<=2000&&dp[v]<0){
                    dp[v]=dp[u]+1;
                    q.push_back(v);    
                }
            }
        }printf("%d
    ",dp[1000]);
        return 0;
    }
    

      

  • 相关阅读:
    H5定位终极解决方案
    软帝学院教你使用cookie法,查看最近看过的书
    你真的会用Gson吗?Gson使用指南(一)
    Java程序员应当知道的10个面向对象设计原则
    java获取当前月第一天和最后一天,上个月第一天和最后一天
    正则基础教程一些冷门的知识
    爆笑的程序员梗,笑死人不偿命!
    java字符串操作扩充:灵活截取字符串
    如何分析及处理 Flink 反压?
    与君初相识,犹如故人归
  • 原文地址:https://www.cnblogs.com/forever97/p/codeforces788c.html
Copyright © 2020-2023  润新知