Codeforces 788 C. The Great Mixing

时间:2025-02-24 11:04:08

题目链接:http://codeforces.com/contest/788/problem/C


  一看就不能暴力$DP$,我们可以将浓度的合并操看作为在追逐一高度,每次操作前这个高度都会向上走$n$,每次加入一定浓度的汽水就增加了相应的高度$a_i$,由于每次都是进行相同的转移,所以一旦高度差的绝对值大于了$1000$,这个状态就没有了意义(因为一定会有等价的状态比他更好),剪枝一下。所以每一次转移就是${O(n*min(k,1000))}$的。

  

 #include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<cstdlib>
#include<cmath>
#include<cstring>
#include<ctime>
#include<map>
using namespace std;
#define maxn 10010
#define llg long long
#define yyj(a) freopen(a".in","r",stdin),freopen(a".out","w",stdout);
llg n,m,k,a[maxn];
bool xian[maxn];
map<llg,bool>ma;
vector<llg>f,nf;
inline int getint()
{
int w=,q=; char c=getchar();
while((c<'' || c>'') && c!='-') c=getchar(); if(c=='-') q=,c=getchar();
while (c>='' && c<='') w=w*+c-'', c=getchar(); return q ? -w : w;
} int main()
{
// yyj("C");
cin>>n>>k;
for (llg i=;i<=k;i++)
{
llg x=getint();
if (xian[x]) continue;
xian[x]=;
a[++m]=x;
}
f.push_back();
for (llg tim=;;tim++)
{
if ((double)clock()/CLOCKS_PER_SEC>0.91) break;
ma.clear();
llg w=f.size(); nf.clear();
for (llg i=;i<w;i++)
{
llg val=f[i];
val-=n;
for (llg j=;j<=m;j++)
{
llg nval=val+a[j];
if (nval==)
{
cout<<tim;
return ;
}
if (nval> || nval<-) continue;
if (ma[nval]) continue;
ma[nval]=;
nf.push_back(nval);
}
}
f.clear();
w=nf.size();
for (llg i=;i<w;i++) f.push_back(nf[i]);
}
cout<<-;
return ;
}