• 牛客题霸--牛能和牛可乐的礼物 题解


    牛能和牛可乐的礼物

    C++版本答案:

    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cmath>
    #include<stack>
    #include<queue>
    #include<vector>
    using namespace std;
    const int MAXN=200020;
    const int MID=100010;
    class Solution {
    public:
      bool vis[2][MAXN];
      queue<int> Q[2];
      int maxPresent(vector<int>& presentVec) {
          int n=presentVec.size();
          memset(vis,0,sizeof(vis))
          int cur=0;Q[cur].push(MID);
          vis[cur][MID]=1;
          for(int i=0;i<n;++i) {
    	const int val=presentVec[i];int nxt=cur^1;
    	while(!Q[nxt].empty()) Q[nxt].pop();
    	while(!Q[cur].empty()) {
    	  int S=Q[cur].front();
    	  vis[cur][S]=0;
    	  if(!vis[nxt][S-val]) vis[nxt][S-val]=1,Q[nxt].push(S-val);
    	  if(!vis[nxt][S+val]) vis[nxt][S+val]=1,Q[nxt].push(S+val);
    	  Q[cur].pop();
    	}
    	cur^=1;
          }
          int ans=1e9;
          for(int i=0;i<MAXN;++i) if(vis[cur][i]) ans=min(ans,abs(i-MID));
          return ans;
      }
    }S;
    vector<int> pr;
    int main()
    {
      int n;cin>>n;pr.resize(n);
      for(int i=0;i<n;++i) scanf("%d",&pr[i]);
      printf("%d
    ",S.maxPresent(pr));
    }
    

    一道简单的动态规划题。
    (f[i][j]) 表示当前到了第 i 件礼物,两组礼物价值和差值为 j 是否可行,将所有j均加上一个偏移量即可避免负数下标的情况。

    假设当前的礼物价值为 (val[i]) , 那么对于 (f[i][j])(true) 时转移
    (f[i+1][j+val[i]]=f[i+1][j-val[i]]=true)
    数组第一维可以滚掉,中间枚举为真的 (f) 时可以用队列实现。
    最后扫描一遍数组得到最小的答案即可。

  • 相关阅读:
    邮件发送
    生成缩略图
    截取字符串,中文安两个字符处理
    获取客户机MAC地址 根据IP地址 获取机器的MAC地址 / 获取真实Ip地址
    文件操作
    MD5加密 和 自定义加密解密
    Html标签替换(过滤掉html特殊符号)
    .net core 自定义中间件
    querySelector和querySelectorAll
    CSS下背景属性background的使用方法
  • 原文地址:https://www.cnblogs.com/NeosKnight/p/13923366.html
Copyright © 2020-2023  润新知