codeforces 789E. The Great Mixing(经典,dp,状态图建立)

题目描述

E. The Great Mixing

分析

稍微分析一下题目,设每一个浓度为 ai 的不同值选了 ki 升,那么,我们有

n1000nkiki(nai)=ni=1aiki1000ni=1ki=aiki=0

即需要求的是在集合 (nai) ,中找到一些数,其中每个值可以取 ki 次,使得他们的和为 0,minki .
由于 ai1000 ,和不会超出1000,(超出,就不会再为0了),我们将每一个和 sum 的值,作为顶点,将 sumsum+ai .就相当于找一个0到0的最小的环,bfs可以搞定了

AC code

#include 
#define INF 0x3f3f3f3f
#define fi first
#define se second



using namespace std;
typedef long long LL;
const int maxn = 2000+10;
int n,k;
int dp[maxn];//距离

int in[maxn];//存在a_i
std::vector<int> v;

void bfs(){
  queue<int> Q;
  for(int i=0 ; i<=1000; ++i){
    if(in[i]){
      v.push_back(n-i);
      int x = n-i+1000;
      dp[x] = 1;
     if(x==1000)break;
      Q.push(x);
    }
  }
  while (!Q.empty()) {
    int x = Q.front();Q.pop();
    for(int i=0 ; iint nt = x+v[i];
      if(nt>=0 && nt<=2000&&dp[nt]>dp[x]+1){
        dp[nt] = dp[x]+1;
        if(nt == 1000)break;
        Q.push(nt);
      }
    }
  }
}


int main(int argc, char const *argv[]) {

  memset(in,0,sizeof(in));
  memset(dp,INF,sizeof(dp));

  cin>>n>>k;
  while (k--) {
    int x;
    scanf("%d",&x );
    in[x] =1;
  }

  bfs();
  if(dp[1000]>=INF){std::cout << "-1" << '\n';}
  else std::cout <1000] << '\n';
  return 0;
}

总结

找固定和的好方法,构建转移图

你可能感兴趣的:(算法刷题)