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


    牛能和牛可乐的礼物

    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) 时可以用队列实现。
    最后扫描一遍数组得到最小的答案即可。

  • 相关阅读:
    浅谈iOS的SDK与API
    ulua-应用层模块编码
    ErlangRoad_2
    ErlangRoad_1
    Git笔记--git使用基本概念和术语
    小米Pro 15.6 系统重装记录
    Ubuntu14.04安装opencv2.4.13
    ubuntu配置机器学习环境(四) 安装intel MKL
    ubuntu配置机器学习环境(三) opencv 安装
    ubuntu配置机器学习环境(二) cuda 和cudnn 安装
  • 原文地址:https://www.cnblogs.com/NeosKnight/p/13923366.html
Copyright © 2020-2023  润新知